Tôi có thể tắt tính năng tự động thanh toán cho một lần xem phụ cụ thể trong thời gian chạy không?


104

Tôi có một chế độ xem cần phải xử lý khung của nó theo chương trình - đó là một loại chế độ xem tài liệu bao bọc nội dung của nó, sau đó được cuộn và thu phóng xung quanh siêu chế độ xem bằng cách thao tác gốc khung. Autolayout đấu với điều này trong thời gian chạy.

Việc tắt hoàn toàn tự động hoàn toàn có vẻ hơi khắc nghiệt vì nó có thể được sử dụng hợp lý để xử lý bố cục cho các chế độ xem khác. Có vẻ như những gì tôi có thể muốn là một số loại "ràng buộc null".

Câu trả lời:


168

Tôi đã từng gặp vấn đề tương tự. Nhưng tôi đã giải quyết nó.
Có, bạn có thể tắt bố cục tự động trong thời gian chạy cho mộtUIView , thay vì tắt nó cho toàn bộ xib hoặc bảng phân cảnh được đặt theo mặc định trong Xcode 4.3 trở lên.

Đặt translatesAutoresizingMaskIntoConstraintsthành YES, trước khi bạn đặt khung của chế độ xem phụ của mình:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

2
Điều này có vẻ như quá mức cần thiết đối với một số trường hợp phức tạp hơn với nhiều chế độ xem. Đối với một cái gì đó đơn giản như thế này, điều này là ổn.
esh

@MuhammadAamirALi xóa subview và sau đó thêm lại nó có thể làm giảm hiệu suất. Chúng tôi có thể lưu trữ giải pháp tốt hơn không?
Nhat Dinh

2
@DinhNhat Tôi đã làm rõ câu trả lời. Việc xóa và thêm lại lượt xem phụ là không cần thiết.
Leandros

5
Nó cho tôi thấy cảnh báo: "Không thể đồng thời thỏa mãn các ràng buộc."
NSPratik

1
Bạn lưu ngày của tôi ... translatesAutoresizingMaskIntoConstraints ... người phát minh thuộc tính như thế này shakinghead
Tintenklecks

50

Tôi đã gặp sự cố tương tự trong đó Autolayout đang ghi đè một số cài đặt khung hình của tôi tại thời điểm chạy (tôi có chế độ xem động mà trong một số trường hợp đã đẩy bộ điều khiển chế độ xem mới ... đẩy và sau đó nhấn Quay lại sẽ đặt lại chế độ xem ban đầu).

Tôi đã giải quyết vấn đề này bằng cách đặt mã thao tác viewDidLayoutSubviewscủa mình vào Bộ điều khiển Chế độ xem của tôi. Điều này dường như được gọi sau khi bất kỳ ràng buộc nào mojo được gọi, nhưng trước viewDidAppear, vì vậy người dùng không ai khôn ngoan hơn.


1
Không hoạt động cho self.navigationItem.titleView. Vẫn không tôn trọng sự thay đổi khung.
Henrik Erlandsson

1
Nếu bạn đang cố gắng kết hợp với khung của chế độ xem tiêu đề, tôi sẽ đặt nó bên trong chế độ xem vùng chứa và thêm chế độ xem vùng chứa làm chế độ xem tùy chỉnh của navigationItem.
jmstone617,

2
Cái này cũng có tác dụng với tôi. Tôi đã lãng phí 2 giờ: 22 phút đập đầu vào bức tường trước khi phát hiện ra cách giải quyết này.
TMc

Cảm ơn, anh bạn. Tôi đang trong ngày thứ hai đấu tranh với vấn đề này và bây giờ nó hoạt động!
Apoolov

28

Có lẽ chỉ cần đặt translatesAutoresizingMaskIntoConstraintsthành YES(và không thêm các ràng buộc bổ sung ảnh hưởng đến chế độ xem đó) sẽ cho phép bạn thiết lập khung hình mà không phải chống lại hệ thống bố cục tự động.


17

Trong iOS 8, bạn có thể đặt NSLayoutConstraint thành hoạt động hoặc không. Vì vậy, nếu tôi đang sử dụng trình tạo giao diện, tôi thêm tất cả các ràng buộc của mình vào OutletCollection và sau đó kích hoạt hoặc hủy kích hoạt bằng cách sử dụng:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

Ứng dụng cụ thể mà tôi đang sử dụng ở đây có các ràng buộc khác nhau ở chế độ dọc và ngang và tôi kích hoạt / hủy kích hoạt dựa trên chuyển động xoay của thiết bị. Điều đó có nghĩa là tôi có thể tạo một số thay đổi bố cục phức tạp trong trình tạo giao diện cho cả hai hướng và vẫn sử dụng bố cục tự động mà không cần mã bố cục tự động dài dòng.

Hoặc bạn có thể kích hoạt / hủy kích hoạt bằng removeConstraints và addConstraints.


Xin lỗi vì đã đánh cắp một câu hỏi cũ như vậy, nhưng tôi có thể hỏi bạn đã quản lý như thế nào để thêm các ràng buộc về bố cục cho các bố cục khác nhau ngay từ đầu? Tôi dường như không thể tìm thấy tùy chọn nào bên trong trình tạo giao diện để bật / tắt các ràng buộc. Hay bạn chỉ cần thêm các ràng buộc cho cả hai bố cục và chỉ bỏ qua trình tạo giao diện phàn nàn về các ràng buộc không hợp lệ (ghi đè)?
Malte

Bạn có thể làm điều đó bằng cách sử dụng các lớp kích thước: developer.apple.com/library/ios/recipes/… , nhưng tôi không thể làm theo cách này vì tôi cũng đang hỗ trợ iOS 7 và các lớp kích thước không hỗ trợ đầy đủ iOS 7 . Tôi đã làm điều đó bằng cách giảm mức độ ưu tiên của ràng buộc xung đột. Không lý tưởng, nhưng nó ngăn cảnh báo. Tôi nghĩ rằng đây là cách tôi đã làm nó anyway ....
bandejapaisa

9

Không biết việc này có giúp ích được gì cho ai không, nhưng tôi viết một chuyên mục để tiện cho việc này vì tôi thấy mình làm việc này rất nhiều.

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

Tôi sử dụng nó như thế này:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

Hy vọng nó giúp.


Xuất sắc ! Tôi đã sử dụng phiên bản sửa đổi của mã của bạn để viết một hàm "hideControl" đơn giản cho bất kỳ UIView nào. Về cơ bản, nó đặt chiều cao của UIView thành 0, nhưng quan trọng là nó sử dụng mã của bạn để làm cho AutoLayout xử lý nó đúng cách (không giống như sử dụng "someView.hiised = TRUE"). Vì vậy, các điều khiển xuất hiện bên dưới điều khiển ẩn và có khoảng cách dọc được liên kết với nó, bây giờ sẽ di chuyển lên trên màn hình để lấp đầy khoảng trống, nơi chế độ xem ẩn đã xuất hiện trước đó.
Mike Gledhill

6

Bạn có thể đặt translatesAutoresizingMaskIntoConstraintsloại Boolean, Giá trị Có trong Thuộc tính thời gian chạy do người dùng xác định của UIView mà bạn muốn trong xib / storyboard.


2
  • Mở dự án trong 4,5
  • Chọn bảng phân cảnh
  • Mở trình kiểm tra tệp
  • Trong Tài liệu Trình tạo Giao diện, bỏ chọn 'Sử dụng Tự động thanh toán'

Bạn có thể chia thành nhiều bảng phân cảnh nếu bạn muốn sử dụng tính năng tự động thanh toán cho một số chế độ xem.


10
Điều đó vô hiệu hóa tính năng tự động thanh toán cho toàn bộ bảng phân cảnh / ngòi. Những gì tôi đang tìm kiếm là một cách (lý tưởng nhất là có lập trình) để có các lượt xem phụ cụ thể trong một bảng phân cảnh / nib không sử dụng autolayout trong khi để phần còn lại làm bất cứ điều gì mà bảng phân cảnh / nib chỉ định.
terriblememory

Bạn có thể sử dụng nhiều bảng phân cảnh và chỉ cần gọi những bảng có / không có tự động thanh toán khi cần: // Khởi tạo bộ điều khiển chế độ xem chi tiết & bảng xếp hạng để hiển thị UIStoryboard * sb = [UIStoryboard storyboardWithName: @ "Storyboard" pack: [NSBundle mainBundle]]; DetailViewController * dvController = [sb InstantiateViewControllerWithIdentifier: entry.viewName];
Mike Bobbitt

1

Đối với tôi, nó hoạt động để tạo chế độ xem phụ theo lập trình, trong trường hợp của tôi, bố cục tự động đang gây rối với chế độ xem mà tôi cần xoay xung quanh trung tâm của nó nhưng khi tôi tạo chế độ xem này theo lập trình, nó đã hoạt động.


1

Theo quan điểm của tôi, tôi đã có Nhãn và Văn bản. Nhãn có cử chỉ xoay. Nhãn di chuyển xung quanh tốt trong quá trình kéo. Nhưng khi tôi sử dụng bàn phím hộp văn bản, nhãn sẽ đặt lại vị trí của nó về vị trí ban đầu được xác định trong bố cục tự động. Sự cố đã được giải quyết khi tôi nhanh chóng thêm phần sau vào nhãn. Tôi đã thêm điều này vào viewWillAppear nhưng nó có thể được thêm vào khá nhiều ở bất cứ đâu bạn có quyền truy cập vào trường mục tiêu.

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

0

Điều này đã xảy ra với tôi trong một dự án không có bảng phân cảnh hoặc tệp xib. Tất cả 100% mã. Tôi có một biểu ngữ quảng cáo ở dưới cùng và muốn giới hạn lượt xem dừng lại ở biểu ngữ quảng cáo. Chế độ xem sẽ tự động thay đổi kích thước sau khi tải. Tôi đã thử mọi giải pháp trên trang này nhưng không có giải pháp nào trong số đó hoạt động.

Tôi đã kết thúc chỉ tạo một chế độ xem phụ với chiều cao được rút ngắn và đặt nó vào chế độ xem chính của bộ điều khiển. Sau đó, tất cả nội dung của tôi đã vào bên trong chế độ xem phụ. Điều đó giải quyết vấn đề rất dễ dàng mà không làm bất cứ điều gì cảm thấy như nó đang đi ngược lại.

Tôi đang nghĩ nếu bạn muốn một chế độ xem không phải là kích thước bình thường lấp đầy cửa sổ thì bạn nên sử dụng một chế độ xem phụ cho điều đó.


0

Tôi đã gặp một trường hợp tương tự, trong đó tôi tham gia một dự án được bắt đầu với bố cục tự động, nhưng tôi cần thực hiện các điều chỉnh động cho một số chế độ xem. Đây là những gì đã làm việc cho tôi:

  1. KHÔNG có các khung nhìn hoặc thành phần được bố trí trong trình tạo giao diện.

  2. Thêm các chế độ xem của bạn hoàn toàn theo chương trình bắt đầu bằng phân bổ / init và thiết lập khung của chúng một cách thích hợp.

  3. Làm xong.


0

Thay vì vô hiệu hóa autolayout, tôi sẽ chỉ tính toán ràng buộc mới với khung mà bạn đang thay thế. Đó là cách thích hợp đối với tôi. Nếu bạn đang điều chỉnh các thành phần dựa trên các ràng buộc, hãy điều chỉnh chúng cho phù hợp.

Ví dụ: nếu bạn có giới hạn dọc bằng 0 giữa hai chế độ xem (myView và otherView) và bạn có cử chỉ xoay hoặc thứ gì đó điều chỉnh chiều cao của myView thì bạn có thể tính toán lại ràng buộc với các giá trị đã điều chỉnh.

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];

0

Đối với những người bạn đang sử dụng bố cục tự động, vui lòng xem giải pháp của tôi tại đây . Bạn nên thực hiện @IBOutletcác ràng buộc bạn muốn điều chỉnh và sau đó thay đổi các hằng số của chúng.


-16

nếu đó là tệp xib:

  1. chọn tệp .xib
  2. chọn "Chủ sở hữu của tệp"
  3. hiển thị các Tiện ích
  4. nhấp vào: "Trình kiểm tra tệp"
  5. Trong "Tài liệu trình tạo giao diện", hãy tắt: "Sử dụng tự động thanh toán"

1
Không, điều đó vô hiệu hóa tự động thanh toán cho toàn bộ xib. Những gì tôi đang tìm kiếm là một cách để chỉ lấy một lượt xem phụ cụ thể ra khỏi hệ thống tự động thanh toán.
terriblememory
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.