18

私はこれを正しくするのに苦労しています。

ページングが有効になっている UIScrollView があります。これはビュー コントローラー (MainViewController) によって管理され、各ページは PageViewController によって管理され、そのビューは適切なオフセットで scrollView のサブビューとして追加されます。標準の向きの iPhone アプリでは、スクロールは左右です。うまくいきます。基本的には Apple が提供するサンプルとまったく同じで、iPhone で提供される Weather アプリも同様です。

しかし、他のオリエンテーションをサポートしようとすると、うまくいきません。このメソッドを使用して、MainViewController と PageViewController の両方ですべての向きをサポートしました。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
     return YES;
}

ただし、デバイスを回転させると、ページがかなり歪んでしまい、特に一部のページのみが読み込まれている場合は、回転してからさらにスクロールするなど、多くの描画の不具合が発生します...非常に面倒です。

ビューに自動サイズ変更をサポートするように指示しました

 theView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

しかし、役に立たない。それは私の見方を引き延ばし、歪めているようです。

すべてのページのビューのサイズを変更するために、MainViewController に次の行を追加しました。

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * ([self.viewControllers count]), self.scrollView.frame.size.height);

    for (int i = 0; i < [self.viewControllers count]; i++) {
        PageViewController *controller = [self.viewControllers objectAtIndex:i];
        if ((NSNull *)controller == [NSNull null])
            continue;

        NSLog(@"Changing frame: %d", i);
        CGRect frame = self.scrollView.frame;
        frame.origin.x = frame.size.width * i;
        frame.origin.y = 0;
        controller.view.frame = frame;
    }
}

しかし、それはあまり役に立ちませんでした (私はビューを遅延ロードしているため、実行時にすべてのビューがロードされるとは限りません)。

この問題を解決する方法はありますか?

4

4 に答える 4

2

UIScrollView のすべてのページに個別の UIViewController (PageViewController) が必要ですか? MainViewController にこれを任せてみませんか。

Interface Builder で UI を構築すると、デバイスを回転させた後にビュー (および一般的な UI) のサイズを変更するのがはるかに簡単になります。

于 2010-09-13T14:52:57.833 に答える
2

以下の方法を使用してこれを成功裏に達成しました:

.h ファイル コード:

@interface ScrollViewController2 : UIViewController <UIWebViewDelegate, UIScrollViewDelegate> {
NSMutableArray *views;
int currentPage;

IBOutlet UIScrollView *scrollView;
BOOL bolPageControlUsed;
int intCurrIndex;

NSMutableArray *arrayContentData;
NSMutableArray *viewControllers;
}

@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;

@property (nonatomic, retain) NSMutableArray *arrayContentData;
@property (nonatomic, retain) NSMutableArray *viewControllers;
@property (nonatomic) BOOL bolPageControlUsed;
@property (nonatomic) int intCurrIndex;

-(void)bindPages;

- (void)setUpScrollView;
- (void)alignSubviews;

- (NSURLRequest *)getPageFromDocumentsDirectory:(NSString *)pstrPageName;

-(void)initiateScrollView;
-(void)loadScrollViewWithPage:(int)page;

================================================== ==========================================

.m ファイル

@synthesize scrollView;

@synthesize arrayContentData、viewControllers、bolPageControlUsed、intCurrIndex;

- (void)viewDidLoad {
[super viewDidLoad];

[self bindPages];

//[self setUpScrollView];

[self initiateScrollView];
}

#pragma mark -
#pragma mark Bind Pages
-(void)bindPages{
self.arrayContentData = [[NSMutableArray alloc] init];

[self.arrayContentData addObject:@"1.html"];
[self.arrayContentData addObject:@"2.html"];
[self.arrayContentData addObject:@"3.html"];
[self.arrayContentData addObject:@"4.html"];
[self.arrayContentData addObject:@"5.html"];
[self.arrayContentData addObject:@"6.html"];

[self.arrayContentData addObject:@"1.html"];
[self.arrayContentData addObject:@"2.html"];
[self.arrayContentData addObject:@"3.html"];
[self.arrayContentData addObject:@"4.html"];
[self.arrayContentData addObject:@"5.html"];
[self.arrayContentData addObject:@"6.html"];

[self.arrayContentData addObject:@"1.html"];
[self.arrayContentData addObject:@"2.html"];
[self.arrayContentData addObject:@"3.html"];
[self.arrayContentData addObject:@"4.html"];
[self.arrayContentData addObject:@"5.html"];
[self.arrayContentData addObject:@"6.html"];

[self.arrayContentData addObject:@"1.html"];
[self.arrayContentData addObject:@"2.html"];
[self.arrayContentData addObject:@"3.html"];
[self.arrayContentData addObject:@"4.html"];
[self.arrayContentData addObject:@"5.html"];
[self.arrayContentData addObject:@"6.html"];
}

#pragma mark - 
#pragma mark Get Filename from Document Directory
- (NSURLRequest *)getPageFromDocumentsDirectory:(NSString *)pstrPageName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *yourFilePath = [NSString stringWithFormat:@"%@/Html/%@", documentDirectory, pstrPageName];
NSURL *url = [NSURL fileURLWithPath:yourFilePath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
return requestObj;
}


#pragma mark -
#pragma mark ScrollView Methods
-(void)initiateScrollView{
views = [[NSMutableArray alloc] initWithCapacity:[self.arrayContentData count]];

NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < [self.arrayContentData count]; i++) {
    [controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];

scrollView.contentSize = CGSizeMake([self.arrayContentData count]*scrollView.bounds.size.width,
                                    scrollView.bounds.size.height);
scrollView.delegate = self;

if(self.intCurrIndex == 0){
    [self loadScrollViewWithPage:self.intCurrIndex];
}
}
-(void)loadScrollViewWithPage:(int)page{
if (page < 0) return;
if (page >= [self.arrayContentData count]) return;

// replace the placeholder if necessary
NSString *strContentName = [self.arrayContentData objectAtIndex:page];

//UIImageView *controller = [viewControllers objectAtIndex:page];
UIWebView *controller = [viewControllers objectAtIndex:page];

if ((NSNull *)controller == [NSNull null]) {

    UIView *v = [[UIView alloc] initWithFrame:scrollView.bounds];
    v.backgroundColor = [UIColor colorWithHue:arc4random()/(float)0x100000000
                                   saturation:0.75
                                   brightness:1.0
                                        alpha:1.0];

    controller = [[UIWebView alloc] initWithFrame:v.bounds];
    controller.delegate = self;
    controller.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    controller.center = CGPointMake(v.bounds.size.width/2, v.bounds.size.height/2);
    [controller loadRequest:[self getPageFromDocumentsDirectory:strContentName]];
    [v addSubview:controller];
    [controller release];

    [scrollView addSubview:v];

    [views addObject:v];
    [viewControllers replaceObjectAtIndex:page withObject:controller];
    [v release];
}

[self alignSubviews];

/*
// add the controller's view to the scroll view
if (nil == controller.superview) {
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    //frame.origin.y = 0;
    controller.frame = frame;
    [scrollView addSubview:controller];
}*/
}
-(void)scrollViewDidScroll:(UIScrollView *)sender{
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
// which a scroll event generated from the user hitting the page control triggers updates from
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
if (self.bolPageControlUsed) {
    // do nothing - the scroll was initiated from the page control, not the user dragging
    return;
}
// Switch the indicator when more than 50% of the previous/next page is visible

currentPage = scrollView.contentOffset.x / scrollView.bounds.size.width;
[self loadScrollViewWithPage:currentPage];
}

// スクロール アニメーションの最後に、スクロールが UIPageControl から発生するときに使用されるブール値をリセットします -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { }

#pragma mark -
#pragma mark setUp ScrollView
- (void)setUpScrollView {
// Set up some colorful content views
views = [[NSMutableArray alloc] initWithCapacity:[self.arrayContentData count]];

for (int i = 0; i < [self.arrayContentData count]; i++) {
    UIView *v = [[UIView alloc] initWithFrame:scrollView.bounds];
    v.backgroundColor = [UIColor colorWithHue:arc4random()/(float)0x100000000
                                   saturation:0.75
                                   brightness:1.0
                                        alpha:1.0];

    NSString *strContentName = [self.arrayContentData objectAtIndex:i];

    UIWebView *controller = [[UIWebView alloc] initWithFrame:v.bounds];
    controller.delegate = self;
    controller.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    controller.center = CGPointMake(v.bounds.size.width/2, v.bounds.size.height/2);
    [controller loadRequest:[self getPageFromDocumentsDirectory:strContentName]];
    [v addSubview:controller];
    [controller release];

    [scrollView addSubview:v];

    [views addObject:v];
    [v release];
}

[self alignSubviews];

[scrollView flashScrollIndicators];
}

#pragma mark -
#pragma mark Align Scroll Subviews
- (void)alignSubviews {
// Position all the content views at their respective page positions
scrollView.contentSize = CGSizeMake([self.arrayContentData count]*scrollView.bounds.size.width,
                                    scrollView.bounds.size.height);

NSUInteger i = 0;
for (UIView *v in views) {
    v.frame = CGRectMake(i * scrollView.bounds.size.width, 0,
                         scrollView.bounds.size.width, scrollView.bounds.size.height);

    for (UIWebView *w in v.subviews) {
        [w setFrame:v.bounds];
    }

    i++;
}
}

#pragma mark -
#pragma mark UIWebView delegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
}
- (void)webViewDidFinishLoad:(UIWebView *)webView { 
}


#pragma mark -
#pragma mark Orientation
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                            duration:(NSTimeInterval)duration {
currentPage = scrollView.contentOffset.x / scrollView.bounds.size.width;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
                                     duration:(NSTimeInterval)duration {
[self alignSubviews];
//NSLog(@"%f", currentPage * scrollView.bounds.size.width);
scrollView.contentOffset = CGPointMake(currentPage * scrollView.bounds.size.width, 0);
}

皆様のお役に立てば幸いです。

乾杯。

于 2012-01-17T19:00:13.483 に答える
1

私はあなたが正しいことを理解しているとは絶対にわかりません。しかし、いくつかの考え:

フレームプロパティは1つ(A)であり、ビューのコンテンツがそこにどのように表示されるか(B)です。フレームCGRectは、スーパービュー(親ビュー)でのビューの(理論上の)境界です。ただし、ビューは必ずしもそのフレーム領域全体を埋める必要はありません

(A)について:ここにはautoresizingMask、スーパービューのサイズが変更されたときにフレームのサイズが変更される方法を設定するUIViewのプロパティがあります。これは、向きを変えると起こります。ただし、通常はデフォルト設定に依存できます(これまでのところ私のために働いています)。

(B)について:ビューフレーム内でのビューコンテンツの分散方法は、UIViewのプロパティで指定されますcontentMode。このプロパティを使用すると、アスペクト比をそのまま維持する必要があることを設定できます。UIViewContentModeScaleAspectFitたとえば、または他の何かに設定します。

ここを参照してください:http: //developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW99

PS:「理論的」と書いたのは、ビューのコンテンツもこれらのフレーム境界を超える可能性があるためです。UIViewのclipsToBoundsプロパティがYESに設定されている場合にのみ、ビューが制限されます。AppleがこれをデフォルトでNOに設定したのは間違いだと思います。

于 2010-04-13T22:37:37.583 に答える
1

Efrainが書いたことに加えて、ビュー変換が恒等変換以外の場合、つまりビューが回転している場合、frameプロパティは無効であることに注意してください。

もちろん、ビューを新しいオフセット位置にする必要があるという事実を説明しましたよね?

于 2010-08-31T18:39:26.397 に答える