【问题标题】:UIScrollView with pages enabled and device rotation/orientation changes (MADNESS)启用页面和设备旋转/方向更改的 UIScrollView (MADNESS)
【发布时间】:2011-02-01 06:56:27
【问题描述】:

我很难做到这一点。

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

但是,当我尝试支持其他方向时,事情并不顺利。我用这个方法支持 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;
    }
}

但这并没有太大帮助(因为我懒惰地加载视图,所以在执行时并非所有视图都必须加载)。

有没有办法解决这个问题?

【问题讨论】:

    标签: objective-c cocoa-touch ios uiscrollview uiinterfaceorientation


    【解决方案1】:

    我不确定我是否理解你的正确.. 但是,一些想法:

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

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

    关于(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 是错误的。

    【讨论】:

      【解决方案2】:

      除了 Efrain 写的内容之外,请注意,如果视图变换不是恒等变换,则 frame 属性无效 - ,当视图旋转时。

      当然,您考虑到您的视图需要位于新的偏移位置,对吧?

      【讨论】:

      • 当其 OWN 转换为标识时,frame 属性在视图上有效。自动旋转的东西使用更深层次的变换(可能是窗口)——位于窗口上的滚动视图实际上并没有改变它自己的变换,可以毫无问题地使用 frame 属性。 OP 似乎没有改变他/她的滚动视图上的显式转换。
      【解决方案3】:

      是否需要为你的 UIScrollView 中的每个页面都有一个单独的 UIViewController(PageViewController)?为什么不让你的 MainViewController 来处理这个。

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

      【讨论】:

      • 我看过那个会议视频,虽然它很有教育意义,但它根本不处理旋转。我已经解决了我的问题,主要是,但没有在这里发布解决方案,因为它很复杂,我只是没有时间。
      【解决方案4】:

      我已经使用以下方法成功实现了这一点:

      .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 滚动视图;

      @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 { self.bolPageControlUsed = 否; }

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

      希望对大家有所帮助。

      干杯。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多