代码之家  ›  专栏  ›  技术社区  ›  jbrennan

启用页面和设备旋转/方向更改的UIScrollView(疯狂)

  •  18
  • jbrennan  · 技术社区  · 15 年前

    我有一个UIScrollView,启用了分页功能。它由一个视图控制器(MainViewController)管理,每个页面都由PageViewController管理,其视图在适当的偏移量处作为scrollView的子视图添加。对于标准方向的iPhone应用程序,滚动是左向右的。效果很好。基本上和苹果提供的样本完全一样,也和iPhone提供的天气应用程序一样。

    然而,当我试图支持其他方向时,事情并不是很好。VIEWCONTROLLER和VIEWCONTROLLER在每个VIEW中都支持

    - (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 回复  |  直到 14 年前
        1
  •  2
  •   Nishant B    13 年前

    我用以下方法成功地实现了这一点:

    @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;
    

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

    @合成滚动视图;

    @合成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];
    }
    

    -(void)ScrollViewDiEndDeceling:(UIScrollView*)滚动视图{ 已使用self.bolpagecontrol=否;

    #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);
    }
    

    我希望这对大家都有帮助。

        2
  •  2
  •   Cœur Gustavo Armenta    5 年前

    是否有必要为UIScrollView中的每个页面都有单独的UIViewController(PageViewController)?为什么不让你的主视图控制器来处理这个问题呢。

    在Interface Builder中构建UI时,在旋转设备后调整视图(以及通常的UI)的大小要容易得多。

        3
  •  1
  •   Efrain    15 年前

    frame属性是一回事(A),视图内容在其中的显示方式是另一回事(B)。框架CGRect是您的视图在超级视图(父视图)中的(理论)边界。。但是,你的观点 不一定需要填充整个框架区域 .

    这是UIView的 autoresizingMask 属性设置调整超级视图大小时如何调整帧的大小。当你改变方向时会发生这种情况。但是,您通常可以依赖于默认设置(到目前为止对我有效)。

    关于(B): contentMode UIViewContentModeScaleAspectFit 比如说,或者别的什么。。

    请看这里: http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/uid/TP40006816-CH3-SW99

    注:我写“理论上的”,因为你的视图内容也可能超过那些框架边界——它们只在UIView的clipsToBounds属性设置为YES时限制视图。我认为苹果默认设置为NO是个错误。

        4
  •  1
  •   Olie    14 年前

    除了Efrain所写的之外,请注意,如果视图转换不是标识转换,则frame属性无效-- ,当视图旋转时。