将viewcontroller中的项约束到导航栏中的项目

时间:2018-01-28 23:27:55

标签: ios objective-c uinavigationcontroller constraints uisearchcontroller

更新:

我原始问题中提出的搜索栏和分段控制器如下所示: enter image description here

我尝试将搜索栏添加为viewDidLoad BrowseViewController {导航控制器中的导航控制器的子视图控制器

[self.navigationController addChildViewController:_searchController];
[self.navigationController.view addSubview:_searchController.searchBar];
_searchController.searchBar.frame = self.navigationController.navigationBar.bounds;
[_searchController didMoveToParentViewController:self.navigationController];

其中呈现: enter image description here

我看来的一切 - 分段控制,桌子 - 都消失了。

UPDATE 我试图将分段控件约束到viewWillLayoutSubviews中的导航控制器视图:

         _segmentedControl.translatesAutoresizingMaskIntoConstraints = NO;
           NSLayoutConstraint *segWidthConst = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:350];

          NSLayoutConstraint *segHeightConst = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:32];

        NSLayoutConstraint *segLeadingConstraint = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.navigationController.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:self.navigationController.navigationItem.titleView.frame.origin.x];

        NSLayoutConstraint *segVerticalConstraint = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.navigationController.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
        [_segmentedControl addConstraints:@[segWidthConst, segHeightConst, segLeadingConstraint, segVerticalConstraint]];

但是我收到了这个错误:

US[5469:1553682] [LayoutConstraints] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x604000295810 UISegmentedControl:0x7face152bc90.leading == UILayoutContainerView:0x7face141a600.leading   (inactive)>
    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2018-01-28 22:18:29.402296-0500 Leaflet-US[5469:1553682] *** Assertion failure in -[UISegmentedControl _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/NSLayoutConstraint_UIKitAdditions.m:734
Impossible to set up layout with view hierarchy unprepared for constraint.
(null)

我有一个UI搜索控制器,我创建并放在viewDidLoad内的导航控制器中:

/*set appearance of search controller */
_searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
_searchController.searchBar.delegate = self;
_searchController.searchResultsUpdater = self;
[_searchController.searchBar sizeToFit];
_searchController.dimsBackgroundDuringPresentation = NO;
self.definesPresentationContext = YES;
_searchController.hidesNavigationBarDuringPresentation = NO;
_searchController.searchBar.searchBarStyle = UISearchBarStyleDefault;
[self.navigationController.navigationBar setBarTintColor:[UIColor blackColor]];
self.navigationController.navigationBar.translucent = NO;
self.navigationItem.titleView = self.searchController.searchBar;

我的视图中也有一个分段控件。我想将分段控件的前导约束与搜索栏的前导约束对齐。

我尝试在viewWillLayoutSubviews

中这样做
_segmentedControl.translatesAutoresizingMaskIntoConstraints = NO;
   NSLayoutConstraint *segWidthConst = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:350];

  NSLayoutConstraint *segHeightConst = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:32];

NSLayoutConstraint *segLeadingConstraint = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:_searchController.searchBar attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0];

NSLayoutConstraint *segVerticalConstraint = [NSLayoutConstraint constraintWithItem:_segmentedControl attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view.safeAreaLayoutGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
[_segmentedControl addConstraints:@[segWidthConst, segHeightConst, segLeadingConstraint, segVerticalConstraint]];

但是,这样做会导致应用程序崩溃:

[LayoutConstraints] The view hierarchy is not prepared for the constraint: 
        <NSLayoutConstraint:0x600000486180 UISegmentedControl:0x7fa647e13620.leading == UISearchBar:0x7fa647f258f0.leading   (inactive)>
When added to a view, the constraint's items must be descendants of that view (or the view itself). 
This will crash if the constraint needs to be resolved before the view hierarchy is assembled. 
Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2018-01-28 18:21:14.589089-0500 Leaflet-US[3891:804350] *** Assertion failure in 
-[UISegmentedControl _layoutEngine_didAddLayoutConstraint:roundingAdjustment:
    mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/NSLayoutConstraint_UIKitAdditions.m:734
Impossible to set up layout with view hierarchy unprepared for constraint.

在查看视图调试时,我看到搜索栏确实不是我的视图控制器的后代(与分段控件不同)。

-UITabBarController 
 -UILayoutContainerView 
  -UitransitionView
   -UIViewControllerWrapperView 
    -UINavigationController
     -UILayoutContainerView
      -UINavigationTransitionView 
       -UIViewControllerWrapperView
        -BrowseViewController 
         -UIView 
          -UISegmentedControl
      -UINavigationBar
       -UIBarBackground
       -UINavigationBarContentView
        -UISearchBar

如果搜索容器视图控制器本身包含在UINavigationController中,如何将我的分段控件约束到我的搜索栏?

2 个答案:

答案 0 :(得分:0)

您可以尝试以下几种方法:

1)仅将segWidthConstsegHeightConst添加到分段控件中;并将其他两个约束添加到导航控制器。

2)获取与导航控制器相关的_searchController.searchBar帧,然后使用帧&#s; sx作为常量将分段控制器固定到导航控制器的视图。

答案 1 :(得分:0)

您应该知道的一件事是您必须在用于定义它的视图的最近祖先视图上添加约束。所以,显然你不应该在段控件上添加前导约束。根据视图层次结构,您可以尝试在UINavigationController的UILayoutContainerView上添加约束,因为它似乎是最近的祖先视图。