【问题标题】:UIScrollView does not scroll in landscape mode - test code and screenshots attachedUIScrollView 在横向模式下不滚动 - 附上测试代码和屏幕截图
【发布时间】:2014-02-19 11:29:46
【问题描述】:

在 Xcode 5.0.2 中,我创建了 a universal app 并将 UIScrollViewUIImageView(其“查看模式”更改为“左上”)拖到 iPhone 和 iPad 故事板中(此处为 fullscreen ):

为了使 UIScrollView 填满整个屏幕,我添加了 4 个约束(此处为 fullscreen):

然后在ViewController.m我尝试:

  1. 加载 board.png(版权所有 Wikipedia Commons,Denelson83)
  2. UIImageView 提供与board.png 相同的维度
  3. UIScrollViewcontentSize 设置为相同大小

这里是源代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIImage *img = [UIImage imageNamed:@"board"];
    NSLog(@"%s: (%f x %f)", __PRETTY_FUNCTION__, img.size.width, img.size.height);
    _imageView.image = img;
    _imageView.frame = CGRectMake(0, 0, img.size.width, img.size.height);
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    _scrollView.contentSize = _imageView.bounds.size;
}

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // fruitless attempt to solve the rotation problem
    _scrollView.contentSize = _imageView.bounds.size;
}

这里是输出:

Scroll[3464:70b] -[ViewController viewDidLoad]: (1000.000000 x 961.500000)

这种方法可行,但有两个问题:

问题一:

当我旋转 iPhone 或 iPad 模拟器时(通过按 Cmd - 左箭头键)- 图像滚动停止工作:

问题 2:

在纵向模式下滚动有效,但我无法到达右下角:

更新 1:

我尝试了 iphonic 的建议(谢谢!),我看到 deviceOrientationDidChange 选择器被调用,但应用程序仍然不滚动:

Scroll[702:70b] -[ViewController viewDidLoad]: image size = {1000, 961.5}
Scroll[702:70b] -[ViewController deviceOrientationDidChange:]: view size = {1000, 961.5}
Scroll[702:70b] -[ViewController deviceOrientationDidChange:]: view size = {1000, 961.5}
Scroll[702:70b] -[ViewController deviceOrientationDidChange:]: view size = {1000, 961.5}

(不过我使用的是_imageView.image.size,因为_imageView.size 在我的sotryboards 中被定义为100 x 100):

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIImage *img = [UIImage imageNamed:@"board"];
    NSLog(@"%s: image size = %@", __PRETTY_FUNCTION__, NSStringFromCGSize(img.size));
    _imageView.image = img;
    _imageView.frame = CGRectMake(0, 0, img.size.width, img.size.height);

    [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector: @selector(deviceOrientationDidChange:)
         name: UIDeviceOrientationDidChangeNotification
         object: nil];
}

-(void)deviceOrientationDidChange:(NSNotification *)notification

{
    _scrollView.contentSize = _imageView.image.size;
    NSLog(@"%s: view size = %@", __PRETTY_FUNCTION__, NSStringFromCGSize(_imageView.image.size));
}

【问题讨论】:

  • 好像ContentSize有问题

标签: ios iphone objective-c uiscrollview rotation


【解决方案1】:
  1. 删除 Orientation 和 viewDidLayoutSubviews 的代码
  2. 在 viewDidLoad 方法中提及 UIScrollView contentSize
  3. 在 XIB 中的绘图部分取消选中 UIScrollView 的 AutoResizeSubview = NO 并选中剪辑子视图。

参考https://github.com/jayaprada-behera/ScrollViewOrientation

- (void)viewDidLoad
{
    [super viewDidLoad];
    //set uiscrollview.autoresizeSubview = NO; in xib
    UIImage *img = [UIImage imageNamed:@"board.png"];
    imageView_.image = img;

    imageView_.frame = CGRectMake(imageScrollView.frame.origin.x, imageScrollView.frame.origin.y, img.size.width, img.size.height);
    imageScrollView.contentSize = imageView_.bounds.size;
}

它会起作用的。

【讨论】:

  • 谢谢。为什么需要设置“剪辑子视图”?
  • 为滚动视图剪辑子视图。这将不允许子视图(此处为 imageview)超出 ScrollView 的范围。
【解决方案2】:

有几件事要补充。

  1. 不要使用bounds,因为在旋转时,框架会发生变化,您需要获取更改后的值,而bounds 的值永远不会更改。

  2. 您的AutoLayout 设置有问题,请尝试将其关闭。

  3. 删除所有用于设置 contentSize 的代码。只需使用下面的代码。

    -(void)viewDidLoad
      {
        [super viewDidLoad];
    
        UIImage *img = [UIImage imageNamed:@"board"];
        NSLog(@"%s: (%f x %f)", __PRETTY_FUNCTION__, img.size.width, img.size.height);
        _imageView.image = img;
        _imageView.frame = CGRectMake(0, 0, img.size.width, img.size.height);
    
        //Handles rotation notifications
        [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil]; 
    }
    
    
    
    -(void)deviceOrientationDidChange:(NSNotification *)notification
    
    {
        _scrollView.contentSize = _imageView.frame.size;
    
        NSLog(@"Size = %@",NSStringFromCGSize(_imageView.frame.size));
    }
    

【讨论】:

  • 不幸的是,这对我不起作用(根本无法滚动)。 origin 不是boundsframe 之间的唯一区别吗?
  • 我得到view size = {100, 100} 因为情节提要中的 UIImageView 大小是 100 x 100...但是如何将其设置为图像大小呢?
  • 您可以在旋转时互换高度和宽度值。使用 UIDeviceOrientation currentOrientation = [[UIDevice currentDevice]orientation];由于错误的自动布局,你得到的图像视图大小为 100,100,我检查了你的代码。关闭自动布局它将起作用..
【解决方案3】:

这就是我制作图像滚动的方式。

  1. 将滚动视图的边缘固定到父视图。
  2. 将图像的边缘固定到滚动视图。
  3. 明确设置图像的宽度和高度约束。
  4. 构建并运行。

在第 1 步中,您可以相对于屏幕定位滚动视图,然后在第 2 步和第 3 步中,您实际上定义了图像的大小以及相对于滚动视图的位置。如果这样做,滚动的内容大小会自动计算,即使旋转更改也不必显式处理。

【讨论】:

  • 是的。类似于您为滚动视图所做的工作。 Storyboard/Xib -> 选择元素 -> 添加约束。
  • “固定边缘”是什么意思?我不是在这里做的吗? i.stack.imgur.com/2CAzN.png(对不起,我编辑的评论滑落了)
  • 这里的想法是确保图像也被固定到滚动视图。因此,对于图像,我可能会更新 6 个约束。 4 表示边缘以及宽度和高度。
【解决方案4】:

在您的源代码中启用了自动布局。我不太了解在动态 imageView 大小的情况下设置约束但是如果你想在没有约束的情况下进行设置,那么请关闭 Mainstoryboard 中的 Autolayout。并以此修改以下方法,

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    UIImage *img = [UIImage imageNamed:@"board"];
    NSLog(@"%s: (%f x %f)", __PRETTY_FUNCTION__, img.size.width, img.size.height);
    _imageView.image = img;
    _imageView.frame = CGRectMake(0, 0, img.size.width, img.size.height);

    _scrollView.contentSize = _imageView.bounds.size;
}

【讨论】:

  • 谢谢,但作为 iOS 新手,我不明白自动布局的建议 - 为什么要关闭它?这对我的应用类型有害吗?
【解决方案5】:

由于您是在情节提要中实例化图像视图,因此无论您在代码中做什么,它的布局都是由自动布局决定的。因此,在代码中设置图像视图的框架没有任何作用。

尽管您没有为图像视图显式配置任何约束(据我所知),Xcode 已经安装了隐式约束。这些约束可能不是您想要的。

此外,您不能明确设置滚动视图的contentSize。相反,contentSize 由图像视图的大小自动确定。

您可能希望在继续之前查看 Apple 的技术说明:https://developer.apple.com/library/ios/technotes/tn2154/_index.html

【讨论】:

    【解决方案6】:

    我自己的解决方案:

    在 Interface Builder 中,我为 UIImageView 分配了宽度和高度,并将其“查看模式”设置为“底部”(此处为 fullscreen):

    ViewController.m 中的以下代码就足够了(不需要旋转检测):

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        UIImage *img = [UIImage imageNamed:@"board"];
        _imageView.image = img;
    }
    
    - (void)viewDidLayoutSubviews
    {
        [super viewDidLayoutSubviews];
    
        _scrollView.contentSize = _imageView.bounds.size;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 2014-08-10
      • 2022-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多