Helpex - Trao đổi & giúp đỡ Đăng nhập
75

Trong iOS 7, giờ đây chúng ta có thể thêm ràng buộc giữa chế độ xem và hướng dẫn bố cục trên cùng, theo tôi nghĩ rất hữu ích để giải quyết vấn đề bù đắp thanh trạng thái trong iOS7 (đặc biệt khi không có thanh điều hướng trong chế độ xem).

Trong tệp bảng phân cảnh, tôi có thể thêm loại ràng buộc này một cách dễ dàng. Chỉ cần giữ phím điều khiển sau đó kéo chế độ xem vào vùng chứa, nó sẽ hiển thị tùy chọn "Top Space to Top Layout Guide".

Có cách nào để thêm ràng buộc giữa chế độ xem và hướng dẫn bố cục trên cùng trong tệp xib không?

Nhưng khi tôi thực hiện thao tác tương tự trong tệp xib, tùy chọn này sẽ biến mất.

Có cách nào để thêm ràng buộc giữa chế độ xem và hướng dẫn bố cục trên cùng trong tệp xib không?

Vì vậy, có cách nào để thêm loại ràng buộc này trong tệp xib không? Hay tôi phải thêm chúng bằng mã?

75 hữu ích 2 bình luận 47k xem chia sẻ
77

Bạn nên tham khảo ví dụ sau, điều này chắc chắn sẽ giúp bạn cho vấn đề của bạn. Tôi nhận được cái này từ http://developer.apple.com .

[button setTranslatesAutoresizingMaskIntoConstraints: NO];
id topGuide = myViewController.topLayoutGuide;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings (button, topGuide);

[myViewController.view addConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat: @"V:[topGuide]-20-[button]"
    options: 0
    metrics: nil
    views: viewsDictionary]
];
77 hữu ích 4 bình luận chia sẻ
14

Đây là giải pháp thay thế của tôi.

Tìm một UIView làm trục xoay, đặt giới hạn bố cục trên cùng của nó một không gian dọc cố định ở trên cùng của vùng chứa.

Control-Kéo ràng buộc bố cục này dưới dạng IBOutlet, chẳng hạn như

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topLayoutConstraint;

Cuối cùng, chỉ cần ghi đè phương thức viewWillLayoutSubviews của UIViewController như sau

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    self.topLayoutConstraint.constant = [self.topLayoutGuide length] + YOUR_TOP_CONSTRSINT;
}

Tất cả các ràng buộc hàng đầu của chế độ xem khác đều dựa trên chế độ xem xoay này, tất cả đã xong :)

14 hữu ích 1 bình luận chia sẻ
9

Từ iOS 9, bạn cũng có thể làm điều đó đơn giản hơn với topLayoutGuide's anchors:

  • Swift 3

view.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor).isActive = true

  • ObjC

[controller.view.topAnchor constraintEqualToAnchor:controller.topLayoutGuide.bottomAnchor].active = YES;

9 hữu ích 1 bình luận chia sẻ
6

Cho đến bây giờ, ngay cả khi sử dụng XCode 6, tôi không thể căn chỉnh các điều khiển với hướng dẫn bố cục hàng đầu trên các tệp .xib. Thay vào đó, tôi đang sử dụng một cách thay thế.

Đầu tiên, trên trình tạo giao diện, tôi vẫn căn chỉnh các điều khiển với đường viền trên cùng của chế độ xem của trình điều khiển chế độ xem.

Sau đó, trong phương thức viewDidLoad, tôi thay thế một số ràng buộc để chúng sẽ căn chỉnh với hướng dẫn bố cục hàng đầu thay vì chế độ xem chính:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSArray *constraints = self.view.constraints;
    for (NSLayoutConstraint *constraint in constraints) {
        if ( (constraint.firstItem == self.view) && (constraint.firstAttribute == NSLayoutAttributeTop) ) {
            NSLayoutConstraint *newConstraint = [self constraint:constraint replaceFirstItemBy:self.topLayoutGuide attribute:NSLayoutAttributeBottom];
            [self.view removeConstraint:constraint];
            [self.view addConstraint:newConstraint];
        } else if ( (constraint.secondItem == self.view) && (constraint.secondAttribute == NSLayoutAttributeTop) ) {
            NSLayoutConstraint *newConstraint = [self constraint:constraint replaceSecondItemBy:self.topLayoutGuide attribute:NSLayoutAttributeBottom];
            [self.view removeConstraint:constraint];
            [self.view addConstraint:newConstraint];
        }
    }
}

- (NSLayoutConstraint*)constraint:(NSLayoutConstraint*)constraint replaceFirstItemBy:(id)newItem attribute:(NSLayoutAttribute)newAttribute {
    UILayoutPriority priority = constraint.priority;
    NSLayoutRelation relation = constraint.relation;
    id secondItem = constraint.secondItem;
    NSLayoutAttribute secondAttribute = constraint.secondAttribute;
    CGFloat multiplier = constraint.multiplier;
    CGFloat constant = constraint.constant;

    NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:newItem attribute:newAttribute relatedBy:relation toItem:secondItem attribute:secondAttribute multiplier:multiplier constant:constant];
    newConstraint.priority = priority;
    return newConstraint;
}

- (NSLayoutConstraint*)constraint:(NSLayoutConstraint*)constraint replaceSecondItemBy:(id)newItem attribute:(NSLayoutAttribute)newAttribute {
    UILayoutPriority priority = constraint.priority;
    id firstItem = constraint.firstItem;
    NSLayoutAttribute firstAttribute = constraint.firstAttribute;
    NSLayoutRelation relation = constraint.relation;
    CGFloat multiplier = constraint.multiplier;
    CGFloat constant = constraint.constant;

    NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:firstItem attribute:firstAttribute relatedBy:relation toItem:newItem attribute:newAttribute multiplier:multiplier constant:constant];
    newConstraint.priority = priority;
    return newConstraint;
}

Hãy nghĩ rằng đây không phải là cách tốt nhất vì chúng tôi thay thế các đối tượng mà chúng tôi xác định trên trình tạo giao diện. Nhưng nó có thể là một cách thay thế mà chúng ta có thể nghĩ đến.

6 hữu ích 0 bình luận chia sẻ
6

Tất nhiên, Bạn không chỉ có thể thêm ràng buộc giữa một chế độ xem và top layout guidehoặc bottom layout guidebằng cách lập trình mà còn có thể xóa và truy cập ràng buộc giữa một chế độ xem và chế độ xem top and bottom layout guidevới sự trợ giúp của thư viện KVConstraintExtensionsMaster .

// create containerView
UIView *containerView = [UIView prepareNewViewForAutoLayout];
[containerView setBackgroundColor:[UIColor brownColor]];
[self.view addSubview:containerView];

// To add Top and Bottom Layout Guide constraint of containerView
[self applyTopLayoutGuideConstraintToView:containerView withPadding:0];
[self applyBottomLayoutGuideConstraintToView:containerView withPadding:50];

// To access top Layout Guide Constraint and update it's constant value.
NSLayoutConstraint *topLayoutGuideConstraint = [self accessAppliedTopLayoutGuideConstraintFromView:containerView];
topLayoutGuideConstraint.constant = 50;

// To access bottom Layout Guide Constraint and update it's constant value with animation
NSLayoutConstraint *bottomLayoutGuideConstraint = [self accessAppliedBottomLayoutGuideConstraintFromView:containerView];
bottomLayoutGuideConstraint.constant = 80;
[self.view updateModifyConstraintsWithAnimation:NULL]; // call this for animation

// To remove Top and Bottom Layout Guide constraint of containerView
[self removeAppliedTopLayoutGuideConstraintFromView:containerView];
[self removeAppliedBottomLayoutGuideConstraintFromView:containerView ];
6 hữu ích 0 bình luận chia sẻ
5

Tôi nghĩ lý do chúng không hiển thị trong XIB là không có kiến ​​thức về hệ thống phân cấp bộ điều khiển chế độ xem trong tình huống đó, trong khi trong bảng phân cảnh IB có thể cho biết vị trí của các hướng dẫn từ hệ thống phân cấp bộ điều khiển chế độ xem mà chế độ xem đang ở. Tức là Nếu nó được chứa trong UINavigationController, nó có thể xác định rằng hướng dẫn bố cục trên cùng nằm bên dưới thanh công cụ điều hướng.

5 hữu ích 1 bình luận chia sẻ
0

Câu trả lời của Cao Hữu Lộc với câu trả lời nhanh 4

extension NSLayoutConstraint {

    func constraintReplacing(firstItemWith newFirstItem: UILayoutSupport, withAttribute newFirstAttribute: NSLayoutAttribute) -> NSLayoutConstraint {
        return NSLayoutConstraint(item: newFirstItem, attribute: newFirstAttribute, relatedBy: relation, toItem: secondItem, attribute: secondAttribute, multiplier: multiplier, constant: constant)
    }

    func constraintReplacing(secondItemWith newSecondItem: UILayoutSupport, withAttribute newSecondAttribute: NSLayoutAttribute) -> NSLayoutConstraint {
        return NSLayoutConstraint(item: firstItem as Any, attribute: firstAttribute, relatedBy: relation, toItem: newSecondItem, attribute: newSecondAttribute, multiplier: multiplier, constant: constant)
    }
}

class YourViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        for constraint in view.constraints {
            if constraint.firstItem === view && constraint.firstAttribute == .top {
                let newConstraint = constraint.constraintReplacing(firstItemWith: topLayoutGuide, withAttribute: .bottom)
                view.removeConstraint(constraint)
                view.addConstraint(newConstraint)
            }
            if constraint.secondItem === view && constraint.secondAttribute == .top {
                let newConstraint = constraint.constraintReplacing(secondItemWith: topLayoutGuide, withAttribute: .bottom)
                view.removeConstraint(constraint)
                view.addConstraint(newConstraint)
            }
        }
    }
}
0 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ ios xcode ios7 xcode5 , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading