【问题标题】:UIStackView and subview size classesUIStackView 和子视图大小类
【发布时间】:2015-11-04 16:02:53
【问题描述】:

我有一个 UIStackView,其中中间按钮仅在不同大小的类中可见 storyboard view

旋转设备后,由于其大小类,按钮将可见,并且也在右侧视图层次结构(图像)中,但 UIstackview 给出的约束不足以正确定位,它位于左上角角(标签中间)。

not enough constraints

工作按钮(不受尺寸等级变化的影响)有更多的限制。

这是一个错误还是我错过了什么。 有人知道解决方法吗?

【问题讨论】:

    标签: ios uistackview


    【解决方案1】:

    这绝对是 iOS 中的一个错误。安装中间按钮后,它被添加为堆栈视图的子视图,而不是作为排列子视图。

    这里有一个解决方法。将中间按钮的自定义类设置为StackViewBugFixButton。然后将中间按钮的(新)priorView 插座连接到左侧的下一个按钮。这是StackViewBugFixButton的定义:

    StackViewBugFixButton.h

    #import <UIKit/UIKit.h>
    
    @interface StackViewBugFixButton : UIButton
    
    @property (nonatomic, weak) IBOutlet UIView *priorSibling;
    
    @end
    

    StackViewBugFixButton.m

    #import "StackViewBugFixButton.h"
    
    @implementation StackViewBugFixButton
    
    - (void)didMoveToSuperview {
        [super didMoveToSuperview];
        [self putIntoArrangedSubviewsIfNeeded];
    }
    
    - (void)putIntoArrangedSubviewsIfNeeded {
        if (![self.superview isKindOfClass:[UIStackView class]]) {
            return;
        }
    
        if (self.priorSibling == nil) {
            NSLog(@"%@ %s You forgot to hook up my priorSibling outlet.", self, __func__);
            return;
        }
    
        UIStackView *stackView = (UIStackView *)self.superview;
        if ([stackView.arrangedSubviews indexOfObject:self] != NSNotFound) {
            return;
        }
    
        NSUInteger priorSiblingIndex = [stackView.arrangedSubviews indexOfObject:self.priorSibling];
        if (priorSiblingIndex == NSNotFound) {
            NSLog(@"%@ %s My priorSibling isn't in my superview's arrangedSubviews.", self, __func__);
            return;
        }
    
        [stackView insertArrangedSubview:self atIndex:priorSiblingIndex + 1];
    }
    
    @end
    

    您将收到一条虚假警告“您忘记连接我的priorSibling 插座”,因为该视图在加载期间被添加为堆栈视图的子视图,而其插座尚未连接。

    【讨论】:

    • 太棒了,效果很好,我做了一点改动,因为我不喜欢插座和拖放,但本质上它是您的解决方案,我会将其发布为我自己问题的答案
    【解决方案2】:

    Rob 和 Uwe 提供的解决方案确实有效,并解决了在 trait 集合更改时未将条件安装视图添加到 arrangedSubviews 的问题。

    我更喜欢解决这个问题,而不必对我希望放置在 UIStackView 中的每个视图进行子类化,因此我将 UIStackView 本身子类化以覆盖 layoutSubviews() 并将孤立的子视图添加到 arrangedSubviews

    class ManagedStackView: UIStackView {
    
        override func layoutSubviews() {
            super.layoutSubviews()
            let unarrangedSubviews = subviews.filter({ !arrangedSubviews.contains($0) })
            unarrangedSubviews.forEach({ insertArrangedSubview($0, atIndex: $0._arrangedSubviewIndex) })
        }
    
    }
    
    
    extension UIView {
    
        private var _arrangedSubviewIndex: Int {
            get {
                return tag
            }
            set {
                tag = newValue
            }
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      感谢 Rob,我使用 swift 创建了以下解决方案,您必须在用户定义的运行时值中设置 controlIndex,但是要设置正确的索引 (see image)

      import UIKit
      
      class UIButtonFixForStackView: UIButton {
      
          var controlIndex:Int = 0
      
          internal override func didMoveToSuperview() {
      
      
          if (superview?.isKindOfClass(UIStackView) == false)
          {
              return
          }
      
          if let stackView = self.superview as? UIStackView
          {
              if stackView.arrangedSubviews.indexOf(self) != nil
              {
                  return
              }
      
              stackView.insertArrangedSubview(self, atIndex: controlIndex)
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        虽然接受的答案应该作为编程方法工作,但值得注意的是,您可以在 Interface Builder 中通过为 Hidden 属性而不是 添加大小类变体来避免此问题已安装 属性。 iOS 正确处理了这种情况,因为 arrangedSubviews 从未真正改变过,而 UIStackViewbuilt to adapt its layout when (arranged) subviews are hidden

        例如,如果您想隐藏紧凑宽度的特定视图,子视图的 IB 配置将如下所示。请注意,该视图已安装所有尺寸类别中:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-27
          • 1970-01-01
          • 1970-01-01
          • 2016-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多