iOs - 将uiview插入代码中的另一个视图,保持约束
Posted
技术标签:
【中文标题】iOs - 将uiview插入代码中的另一个视图,保持约束【英文标题】:iOs - insert uiview into another view in code, keep constraints 【发布时间】:2014-05-30 15:33:14 【问题描述】:我正在努力实现的目标。 每当我有一个从我的类 SuperViewController 继承的 UIViewController 时,在我的超级视图控制器的 viewDidLoad 中,我会获取我的 UIViewController 的所有子视图,创建一个 UIScrollView,将所有子视图添加到它并将这个 UIScrollView 设置为 UIViewController 的唯一子级。
调用[super viewDidLoad]之前的UIViewController结构;
UIViewController
UIView
subview1
subview2
subview3
之后
UIViewController
UIView
UIScrollView
subview1
subview2
subview3
将涉及 UIView - 子视图的约束移至 UIScrollView-subviews
我这样做的原因是因为在我们的应用程序中我们有很多处理滚动视图,我只想编写代码将它们添加到超类中并让它根据内容启用/禁用滚动大小。
我目前在我的 superviewController(simplified) 中有什么
- (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];
但这不会产生我想要的视图层次结构。
【问题讨论】:
你的解决方案最后奏效了吗? 【参考方案1】:如果你需要像 ViewController 的根视图一样加载 ScrollView,你需要重写 loadView
方法而不像这样调用 super:
-(void)loadView _scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; [自我 setView:self.scrollView];
约束不适用于 AutoresizeMask。如果您向视图添加约束,则需要设置此视图 [view setAutoresizingMask:NO];
否则您会遇到冲突。
在设置约束之前添加子视图。
【讨论】:
谢谢,我的问题是 2 和 3以上是关于iOs - 将uiview插入代码中的另一个视图,保持约束的主要内容,如果未能解决你的问题,请参考以下文章
如何使用动画概念将一个 UIview 推送到 ios 中的另一个 UIview?
检测一个 UIView 是不是在父级中的另一个 UIView 后面