【问题标题】:UIBarButtonItem with separate portrait and landscape images - layoutSubviews not called when popping a view controller from UINavigationControllerUIBarButtonItem 具有单独的纵向和横向图像 - 从 UINavigationController 弹出视图控制器时未调用 layoutSubviews
【发布时间】:2013-03-12 06:12:26
【问题描述】:

我想在 UINavigationController 的 UIToolbar 中显示完全自定义的按钮,并支持纵向和横向。目前我已经实现了一个 RotatingButton(一个 UIView 子类)类,它包含一个填充整个 RotatingButton 框架的 UIButton。 RotatingButton 还包含两个图像,用于纵向和横向,并且这些图像的高度不同。然后这个 RotatingButton 被包装到 UIBarButtonItem 作为一个自定义视图。

目前,在 RotatingButton 的 layoutSubviews 中,我正在设置整个视图的边界,并将按钮设置为当前方向的适当图像。这很好用,可以根据需要处理旋转。

- (void) createLayout {
    [self addButtonIfNeeded];
    UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
    if(UIInterfaceOrientationIsLandscape(currentOrientation)) {
        [self.button setImage:self.landscapeImage forState:UIControlStateNormal];
        self.button.frame = CGRectMake(0.0, 0.0, self.landscapeImage.size.width / 2, self.landscapeImage.size.height / 2);
        self.bounds = CGRectMake(0.0, 0.0, self.landscapeImage.size.width / 2, self.landscapeImage.size.height / 2);
    } else {
        [self.button setImage:self.portraitImage forState:UIControlStateNormal];
        self.button.frame = CGRectMake(0.0, 0.0, self.portraitImage.size.width / 2, self.portraitImage.size.height / 2);
        self.bounds = CGRectMake(0.0, 0.0, self.portraitImage.size.width / 2, self.portraitImage.size.height / 2);
    }
}

- (void) layoutSubviews {
    [super layoutSubviews];
    [self createLayout];
}

但是,这个问题仍然存在:

  1. 纵向开始视图
  2. 将视图控制器推入堆栈
  3. 将设备旋转到横向(当前视图会做出适当反应)
  4. 弹出最后一个视图控制器:前一个视图反应良好,但 RotatingButtons 的 layoutSubviews 没有被调用,按钮仍然比它们应该的大

因此,当前在弹出视图控制器后,之前的 UIBarButtonItems 没有调用它们的 layoutSubviews,并且它们仍然太大(或者太小,如果我们从横向开始并在另一个视图中旋转到纵向)。如何解决这个问题?

【问题讨论】:

    标签: iphone objective-c uinavigationcontroller uibarbuttonitem uitoolbar


    【解决方案1】:

    这是一个非常棘手的问题。您应该尝试覆盖 viewWillAppear: 以调用 [self.view setNeedsLayout] 以在视图即将出现时强制进行布局更新。

    【讨论】:

    • 这听起来像是一个很有前途的想法,但由于某种原因它对我不起作用,我的猜测是 [self.view setNeedsLayout] 并没有真正影响导航控制器的 UIToolbars 布局行为。此外,由于我在整个应用程序中都使用这些自定义按钮,我更喜欢不是每个视图控制器都必须包含此类代码的解决方案。不过,我认为这是可以接受的。
    • 你试过[self.navigationController.view setNeedsLayout]吗?
    • 是的,我也认为值得尝试 [self.navigationController.toolbar setNeedsLayout],但无济于事:(。
    • 当然是 [self.navigationController.navigationBar setNeedsLayout]。
    【解决方案2】:

    我没有找到完全满意的解决方案,但我的按钮大小正好合适,这种解决方案对我来说效果很好:

    UIBarButtonItem* b = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:target action:selector];
    UIImage *barButton = [portraitImage resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
    UIImage *barButton_land = [landscapeImage resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)];
    [b setBackgroundImage:barButton forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [b setBackgroundImage:barButton_land forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
    

    然后显然将创建的按钮添加为 rightBarButtonItem/leftBarButtonItem,或者您可能想要使用它。

    这样做的问题是,如果您的按钮不够宽,按钮可能看起来完全错误(因为在此解决方案中图像的中间内容是平铺的)。

    【讨论】:

      猜你喜欢
      • 2014-02-07
      • 1970-01-01
      • 2012-12-21
      • 2013-01-15
      • 1970-01-01
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多