2014-10-22 18 views
16

Trước đó tôi phải nói rằng tôi thực sự có hiệu ứng hiển thị mà tôi muốn nhưng không theo cách thỏa mãn, ngay bây giờ, các ràng buộc cần phải "bị hỏng" thay vì được cập nhật đúng cách.Chế độ xem không cập nhật sau khi thay đổi ràng buộc bố cục tự động theo lập trình

Tôi có một ViewController chứa một UITableView. Chiều cao của tableView có thể thay đổi từ 0 (không hiển thị) đến bất kỳ số lượng hàng mà nó nắm giữ. Chiều cao được tính trong viewDidLoad của ViewController() bằng cách nhân số hàng hiện tại theo chiều cao của hàng.

Điều đầu tiên tôi đã thử đang tạo một @IBOutlet weak var tableHeightConstraint: NSLayoutConstraint! được kết nối với giới hạn chiều cao được đặt trong bảng phân cảnh. Nó có chỉ số chiều cao ban đầu ngẫu nhiên nhưng nó được cập nhật với giá trị đúng trong phạm vi của ViewController viewDidLoad() tiếp theo phương pháp cập nhật xem nếu cần thiết:

tableHeightConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: calculatedTableViewHeight) 

// At this point I've tried a variety of methods like the following two but actually none has worked for me 
view.layoutIfNeeded() 

// or 
view.updateConstraints() 

// or 
view.layoutSubviews() 

... và ngay cả những phương pháp tương tự trên tableView chỉ để đảm bảo cũng như đặt tất cả những thứ này vào viewDidLayoutSubviews() thay thế.

Vì vậy, những gì tôi đã thử tiếp theo là tạo ra cùng một ràng buộc như trên nhưng thay vì cập nhật tôi chỉ cần thêm nó vào chế độ xem: view.addConstraint(tableHeightConstraint). Điều này thực sự đã có hiệu ứng hình ảnh mong muốn nhưng trong các bản ghi tôi nhận được một cuộc xung đột của hai ràng buộc chiều cao này dẫn đến một sự phá vỡ của một trong những ban đầu. Vì mục tiêu của tôi là lấy mã đúng và sạch mà tôi đã cố gắng. Vì vậy, lần này tôi lần đầu tiên loại bỏ các ràng buộc từ xem trước khi thêm một điều chỉnh một lần nữa. Nhìn bề ngoài, một lần nữa, mọi thứ đều hoàn hảo nhưng tôi vẫn không loại bỏ được những ràng buộc xung đột. Vì vậy, câu hỏi thực tế của tôi là (ngoài những gì tôi đã làm sai cho đến nay) làm thế nào tôi có thể - tốt hơn - chỉ cập nhật một ràng buộc hiện có theo sau là một cập nhật/chuyển tiếp thích hợp của khung nhìn và các phần phụ của nó tại bất kỳ thời điểm nào, cho dù đó là khi lần đầu tiên tôi tải chế độ xem hoặc liệu tôi có muốn thay đổi một số ràng buộc khi người dùng tương tác hay không. Cảm ơn rất nhiều vì đã giúp đỡ!

+0

Đặt thuộc tính thành ràng buộc mới không loại bỏ ràng buộc cũ, nó chỉ làm cho con trỏ của bạn trỏ đến điểm mới, đó là lý do tại sao bạn nhận được các ràng buộc xung đột. Bạn nên làm điều đó như trong câu trả lời của @cmyr. – rdelmar

+0

@rdelmar Ok, hiểu rồi, cảm ơn lời giải thích này! Nhưng tại sao vẫn còn một xung đột khi đi tới 'view.removeConstraint (tableHeightConstraint)', tạo ra một cái mới và thêm nó một lần nữa vào khung nhìn bởi 'view.addConstraint (tableHeightConstraint)'? Chỉ vì lý do hiểu biết ... –

+1

Xem trong tuyên bố đó là gì? Có phải self.view của controller không? Giới hạn chiều cao mà bạn thực hiện trong bảng phân cảnh được thêm vào chế độ xem bạn đặt chiều cao của, chế độ xem bảng trong trường hợp của bạn (không phải trên màn hình giám sát). Bạn đã thử, self.tableView.removeConstraint (tableHeightConstraint)? Người mới cũng nên được thêm vào chế độ xem bảng. – rdelmar

Trả lời

29

Hiện tại, bạn đang chỉ định một ràng buộc mới, thay vì cập nhật hạn chế hiện tại. Ràng buộc mới cũng chưa được thêm vào phân cấp khung nhìn.

cách tiếp cận của bạn sử dụng một IBOutlet để tham khảo một hạn chế bạn thiết lập trong IB là một phương pháp tốt, nhưng thay vì gán một ràng buộc mới để var đó, bạn chỉ cần phải sửa đổi của chế liên tục:

tableHeightConstraint.constant = calculatedTableHeight.

Bạn không cần phải gọi layoutIfNeeded() ở đây, vì các ràng buộc xử lý việc gọi một cách bố trí tự động chuyển khi bạn thay đổi hằng số của chúng. updateConstraints()layoutSubviews() chắc chắn không phải là thứ bạn muốn.

+0

Tôi thực sự muốn có thể chỉ đơn giản là thay đổi con trỏ để tham khảo một hạn chế khác nhau, để chuyển đổi giữa 2 chế độ thanh lịch hơn. Nhưng dường như không có thông báo cập nhật nào sẽ gây ra ràng buộc mới được tham chiếu để thay thế ràng buộc trước đó. Tôi có bị mắc kẹt khi phải thêm và loại bỏ các ràng buộc trong câu hỏi mỗi khi tôi muốn thay đổi chế độ? – Michael

+0

@Michael: tham chiếu bạn đang nắm giữ với ràng buộc là để sử dụng riêng của bạn; nếu bạn thêm một ràng buộc vào một khung nhìn và không lưu một tham chiếu đến nó ở bất kỳ đâu, nó vẫn được thêm vào khung nhìn. – cmyr

+0

Vâng, điều đó có ý nghĩa; dễ hiểu hơn khi bạn nghĩ về các ràng buộc trên một khung nhìn đơn giản như một mảng các mục. Một ràng buộc XIB được liên kết với một IBOutlet chỉ là một cách để khởi tạo ràng buộc và thêm nó vào mảng trên lần tải đầu tiên. Thay đổi con trỏ trong bộ điều khiển của bạn không thay đổi những gì đã có trong mảng, trong khi thay đổi một thuộc tính trên ràng buộc (tức là hằng số) thay đổi một giá trị và có một hiệu ứng thực tế. – Michael

Các vấn đề liên quan