iOs - 将 uiview 插入代码中的另一个 View ,保持约束

标签 ios uiview uiscrollview autolayout nslayoutconstraint

我正在努力实现的目标。 每当我有一个继承 self 的类 SuperViewController 的 UIViewController 时,在我的 super View Controller 的 viewDidLoad 中,我获取我的 UIViewController 的所有 subview ,创建一个 UIScrollView,将所有 subview 添加到它并将此 UIScrollView 设置为 UIViewController 的唯一 subview 。

调用[super viewDidLoad]前的UIViewController结构;

UIViewController
  UIView
     subview1
     subview2
     subview3

之后

UIViewController
  UIView
    UIScrollView
       subview1
       subview2
       subview3

关于 UIView - subview 的约束,移动到 UIScrollView-subviews

我这样做的原因是因为在我们的应用程序中我们有很多处理 scrollViews 的事情,我只想编写代码将它们添加到父类(super class)中并让它根据内容启用/禁用滚动大小。

我目前在我的 superviewController 中有什么(简化)

 - (void)viewDidLoad
{
    [super viewDidLoad];

     if([self class]!=[SuperViewController class] && [self isKindOfClass:[SuperViewController class]])
     {
        //subclass called this method
         UIScrollView *scrollViewToAdd = [[UIScrollView alloc] init];
         UIView *originalView = self.view;

         NSArray* savedConstraints = self.view.constraints;
         for (UIView* view in self.view.subviews)
         {
            [scrollViewToAdd addSubview:view];
         }

         for (NSLayoutConstraint*oldConstr in savedConstraints)
         {
               //loop through all of the constraints associated with the UIView. If one of the items is UIView, replace it with UIScrollView
               //add all of these constraints to UIScrollView
               NSLayoutConstraint *newConstraint = [NSLayoutConstraint    constraintWithItem:oldConstr.firstItem==self.view?scrollViewToAdd:oldConstr.firstItem  attribute:oldConstr.firstAttribute relatedBy:oldConstr.relation  toItem:oldConstr.secondItem==self.view?scrollViewToAdd:oldConstr.secondItem  attribute:oldConstr.secondAttribute multiplier:oldConstr.multiplier constant:oldConstr.constant];
              newConstraint.priority = oldConstr.priority;
              [scrollViewToAdd addConstraint:newConstraint];

        }

     }
     //moving the subviews sets self.view to nil, thankfully i kept a reference so i can set it to the original value
     _scrollView = scrollViewToAdd;
     self.view = originalView;
     //add scrollview as a child
     [self.view addSubview:_scrollView];

     //add scrollView constraints
     id topGuide =self.topLayoutGuide;
     id bottomGuide = self.bottomLayoutGuide;

    _scrollViewToTop =  [[NSLayoutConstraint constraintsWithVisualFormat: @"V: [topGuide]-0-[_scrollView]"
                                                              options: 0
                                                              metrics: nil
                                                                views: NSDictionaryOfVariableBindings (topGuide, _scrollView )] firstObject];


    _scrollViewToBottom =  [[NSLayoutConstraint constraintsWithVisualFormat: @"V:[_scrollView]-0-[bottomGuide]"
                                                                options: 0
                                                                metrics: nil
                                                                  views:      NSDictionaryOfVariableBindings (bottomGuide, _scrollView)] firstObject];


     [self.view addConstraint:_scrollViewToTop];
     [self.view addConstraint:_scrollViewToBottom];




 }

这给了我不明白的约束冲突

 (
"<_UILayoutSupportConstraint:0xb866db0 V:[_UILayoutGuide:0xf9b2750(0)]>",
"<_UILayoutSupportConstraint:0xb866cf0 V:|-(0)-[_UILayoutGuide:0xf9b2750]   (Names: '|':UIView:0x9e90480 )>",
"<_UILayoutSupportConstraint:0xb866f90 V:[_UILayoutGuide:0xb862070(0)]>",
"<_UILayoutSupportConstraint:0xb866ec0 _UILayoutGuide:0xb862070.bottom == UIView:0x9e90480.bottom>",
"<NSLayoutConstraint:0xb87a710 V:[_UILayoutGuide:0xf9b2750]-(0)-[UIScrollView:0x9e84b00]>",
"<NSLayoutConstraint:0xb861e80 V:[UIScrollView:0x9e84b00]-(0)-[_UILayoutGuide:0xb862070]>",
"<NSAutoresizingMaskLayoutConstraint:0xf9a5280 h=--& v=--& UIScrollView:0x9e84b00.midY ==>",
"<NSAutoresizingMaskLayoutConstraint:0xf992950 h=-&- v=-&- UIView:0x9e90480.height == UIViewControllerWrapperView:0xb87bd20.height - 64>",
"<NSAutoresizingMaskLayoutConstraint:0xb870f90 h=-&- v=-&- UIViewControllerWrapperView:0xb87bd20.height == UINavigationTransitionView:0x9a6e3e0.height>",
"<NSAutoresizingMaskLayoutConstraint:0xf9b3560 h=-&- v=-&- UINavigationTransitionView:0x9a6e3e0.height == UILayoutContainerView:0x9a6dd10.height>",
"<NSLayoutConstraint:0xb876390 'UIView-Encapsulated-Layout-Height' V:[UILayoutContainerView:0x9a6dd10(480)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xb861e80 V:[UIScrollView:0x9e84b00]-(0)-[_UILayoutGuide:0xb862070]>

如果不是

,我可以消除这个冲突
     self.view = originalView;
     [self.view addSubview:_scrollView];

我愿意

     [self.view = _scrollView];

但这不会产生我想要的 View 层次结构。

最佳答案

  1. 如果您需要像 ViewController 的 Root View 一样加载 ScrollView,您需要重写 loadView 方法,而无需像这样调用 super:

    -(void)loadView { _scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; [自行设置 View :self.scrollView];

  2. 约束不适用于 AutoresizeMask。如果您向 View 添加约束,则需要设置此 View [view setAutoresizingMask:NO]; 否则您会遇到冲突。

  3. 在设置约束之前添加 subview 。

关于iOs - 将 uiview 插入代码中的另一个 View ,保持约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23958238/

相关文章:

iOS 7 : UINavigationController pulls down UIScrollview

ios - ScrollView 不缩放和水平滚动一起吗?

ios - 带有 RoboVM 的适用于 iOS 的 Libgdx - IOSGLES20.init 中的不满意链接错误

ios - 表中的 UISwitch 在切换状态打开时选择多个单元格

iphone, ipad 复制 UIView - 克隆 View

iOS - 一次不分配太多内存

ios - 内容偏移动画损坏

ios - 播放用 AVFoundation 录制的视频

ios - firebase 在哪里将所有设备 token 内部保存在他们的云中?

iOS - 如何在不同的 UITableViewCell 中重新使用 UIView