Làm cách nào để tôi có thể thiết lập các ràng buộc tỷ lệ khung hình trong iOS?


85

Tôi đã sử dụng bố cục tự động cho bộ điều khiển chế độ xem của mình. Tôi đã đặt các vị trí V và H trong các ràng buộc, nhưng tôi muốn biết làm cách nào để tăng kích thước nút của mình khi nó thay đổi thành 5s, 6 và 6 Plus. Đây là cách tôi thêm các ràng buộc cho nút đăng nhập:

NSArray *btncon_V=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[btnLogin(40)]" options:0 metrics:nil views:viewsDictionary];
[btnLogin addConstraints:btncon_V];

NSArray *btncon_POS_H=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[btnLogin]-100-|" options:0 metrics:nil views:viewsDictionary];
[self.view addConstraints:btncon_POS_H];


NSArray *btncon_POS_V=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-70-[Title]-130-[lblFirst]-0-[lblSecond]-20-[textusername]-10-[txtpassword]-10-[btnLogin]" options:0 metrics:nil views:viewsDictionary];

[self.view addConstraints:btncon_POS_V];

Nhưng vấn đề của tôi là trong khi nó quản lý khoảng cách bên trái và bên phải, nó đang bị kéo dài trong iPhone 6 và 6 Plus vì chiều cao được cố định. Làm thế nào để tôi có thể tăng kích thước theo kích thước màn hình? Tôi nghĩ đây có thể là tỷ lệ khung hình, nhưng làm cách nào để đặt giới hạn tỷ lệ khung hình trong mã?


2
Kiểm tra câu trả lời này: stackoverflow.com/a/12526630/3202193
Ashish Kakkad

Câu trả lời:


84

Như thế này. Thử một lần.

[self.yourview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.yourview addConstraint:[NSLayoutConstraint
                                  constraintWithItem:self.yourview
                                  attribute:NSLayoutAttributeHeight
                                  relatedBy:NSLayoutRelationEqual
                                  toItem:self.yourview
                                  attribute:NSLayoutAttributeWidth
                                  multiplier:(self.yourview.frame.size.height / self.yourview.frame.size.width)
                                  constant:0]];

hoặc ở vị trí của (self.yourview.frame.size.height / self.yourview.frame.size.width)bạn có thể sử dụng bất kỳ giá trị float nào. Cảm ơn.

Swift 3.0 -

self.yourview!.translatesAutoresizingMaskIntoConstraints = false
self.yourview!.addConstraint(NSLayoutConstraint(item: self.yourview!,
                                          attribute: NSLayoutAttribute.height,
                                          relatedBy: NSLayoutRelation.equal,
                                          toItem: self.yourview!,
                                          attribute: NSLayoutAttribute.width,
                                          multiplier: self.yourview.frame.size.height / self.yourview.frame.size.width,
                                          constant: 0))

Nó mang lại cho tôi lỗi này Chấm dứt ứng dụng do không có ngoại lệ 'NSInternalInconsistencyException', lý do: 'Hệ số nhân không phải là hữu hạn! Đó là bất hợp pháp. multiplier: nan'
IRD

2
nó có nghĩa là trong trường hợp như nếu chiều cao là 100 và chiều rộng là 200 và bạn đã cho hệ số 0,5 với mã của tôi, thì nếu chiều cao của bạn tăng lên 150 bằng cách thay đổi bất kỳ ràng buộc nào khác thì chiều rộng sẽ tự động tăng lên 300. Nhưng để làm điều này, bạn cần để tăng một hạn chế của chế độ xem như chiều rộng hoặc chiều cao.
Mahesh Agrawal

1
nó sẽ lấy chiều cao: chiều rộng = 1: 2 tức là 0,5.
Mahesh Agrawal

3
Đừng quên thêm dòng này trước khi cài đặt bất kỳ trở ngại programatically: [self.yourview setTranslatesAutoresizingMaskIntoConstraints:NO];
atulkhatri

1
Khi sử dụng các ràng buộc, kích thước khung hình của tôi đều bằng không. Để có được tỷ lệ khung hình, thay vào đó, tôi đã sử dụngself.yourview.intrinsicContentSize
Phlippie Bosman

88

Layout Anchors là cách thuận tiện nhất để thiết lập các ràng buộc theo chương trình.

Giả sử bạn muốn đặt tỷ lệ co 5: 1 cho nút của mình thì bạn nên sử dụng:

button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1.0/5.0).isActive = true

Đây là mã đầy đủ:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .custom)
        button.setTitle("Login", for: .normal)
        button.backgroundColor = UIColor.darkGray

        self.view.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false

        let margins = view.layoutMarginsGuide

        button.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20.0).isActive = true
        button.trailingAnchor.constraint(equalTo: margins.trailingAnchor, constant: -20.0).isActive = true
        button.bottomAnchor.constraint(equalTo: margins.bottomAnchor, constant: -20.0).isActive = true
        button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1.0/5.0).isActive = true
    }

}

Đây là kết quả đạt được với đoạn mã được viết ở trên. Bạn có thể thấy nút đó giữ tỷ lệ khung hình 5: 1 trên các thiết bị khác nhau:

Xem kết quả


14

Swift 3:

yourView.addConstraint(NSLayoutConstraint(item: yourView,
                                          attribute: .height,
                                          relatedBy: .equal,
                                          toItem: yourView,
                                          attribute: .width,
                                          multiplier: 9.0 / 16.0,
                                          constant: 0))

1
Đối với iOS 8 trở lên, bạn nên sử dụng thuộc tính isActive của NSLayoutConstraint thay vì gọi addConstraint (:). aspectRatioConstraint.isActive = true
dvdblk

Tại sao bạn không sử dụng .widthlàm thuộc tính đầu tiên? Kết quả là attr2 * multiplier , tỷ lệ khung hình là width / height, vì vậy width = height * aspectRatio, nếu chúng ta đặt .heightthuộc tính đầu tiên và thuộc tính aspectRatiođến multiplierthì kết quả hoàn toàn đảo ngược.
Kimi Chiu

12

Bạn có thể đặt "Giới hạn chiều cao" tại thời điểm Thiết kế trong Trình tạo giao diện. Chỉ cần chọn '"Xóa tại thời điểm xây dựng" và nó sẽ xóa khi Ứng dụng chạy.

nhập mô tả hình ảnh ở đây Sau đó, bạn có thể thêm ràng buộc "Tỷ lệ khung hình", ví dụ, trong phương thức viewDidLoad.

Trong Xamain.iOS cho "16: 9", nó trông như thế này:

    this.ImageOfTheDay.AddConstraint(NSLayoutConstraint.Create(
            this.ImageOfTheDay,
            NSLayoutAttribute.Height,
            NSLayoutRelation.Equal,
            this.ImageOfTheDay,
            NSLayoutAttribute.Width,
            9.0f / 16.0f,
            0));

Hoặc, như Mahesh Agrawal đã nói:

    [self.ImageOfTheDay addConstraint:[NSLayoutConstraint
                              constraintWithItem:self.ImageOfTheDay
                              attribute:NSLayoutAttributeHeight
                              relatedBy:NSLayoutRelationEqual
                              toItem:self.ImageOfTheDay
                              attribute:NSLayoutAttributeWidth
                              multiplier:(9.0f / 16.0f)
                              constant:0]];

12

Tiện ích mở rộng trình trợ giúp trên UIView

extension UIView {

    func aspectRation(_ ratio: CGFloat) -> NSLayoutConstraint {

        return NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: self, attribute: .width, multiplier: ratio, constant: 0)
    }
}

Và cách sử dụng là:

view.aspectRation(1.0/1.0).isActive = true


và sử dụng: view.aspectRation (1.0 / 1.0)
Michał Ziobro

1
Đây thực sự là một giải pháp thanh lịch chặn vài loại: 1. Tham số Các toItem được thiết lập để .selfthay vì self2. Và việc sử dụng trong bình luận nên view.aspectRation(1.0/1.0).isActive = true tôi thử nghiệm này trong Xcode 10.2.1 Swift 5.
Pankaj Kulkarni

3

Tôi đã thử tất cả các câu trả lời ở trên nhưng không hiệu quả và đây là giải pháp của tôi với swift 3:

let newConstraint = NSLayoutConstraint(item: yourView, attribute: .width, relatedBy: .equal, toItem: yourView, attribute: .height, multiplier: 560.0/315.0, constant: 0)
yourView.addConstraint(newConstraint)
NSLayoutConstraint.activate([newConstraint])  
NSLayoutConstraint.deactivate(yourView.constraints)
yourView.layoutIfNeeded()

Bạn nên luôn luôn tắt (có khả năng mâu thuẫn) trở ngại trước khi thêm những cái mới để tránh autolayout lỗi
John

0

Đối với khung nhìn, có những ràng buộc và cũng có những thuộc tính.

tỷ lệ khung hình là một thuộc tính của chế độ xem , vì vậy bạn có thể đặt nó bằng cách sử dụng chế độ nội dung, như vậy

imageView.contentMode = .scaleAspectFit

điều này sẽ đạt được rằng một chế độ xem không thay đổi tỷ lệ nếu chẳng hạn

  • chiều cao hoặc chiều rộng lớn hơn sẽ phù hợp trên màn hình
  • chiều cao được mã hóa cứng và do đó sẽ không thể thích ứng với các kích thước màn hình khác nhau.

Câu hỏi không phải về ImageView và chế độ nội dung của nó, mà là về bố cục tự động và các ràng buộc. Từ Trình tạo giao diện, bạn có thể đặt giới hạn tỷ lệ khung hình mà ở cuối tạo giới hạn chiều rộng đến chiều cao với một hệ số.
Gunhan

@Gunhan câu hỏi liên quan đến cách đặt nó theo chương trình. Vì vậy, có thể thiết lập nó trong trình xây dựng giao diện là điều tốt để biết, nhưng không liên quan đến câu hỏi này.
valeriana

Tôi nghĩ rằng bạn đã hiểu sai những gì tôi nói trước đó. Trong câu hỏi này, không ai nói về ImageView. CNTT là về bố cục và ràng buộc tự động, và phải làm cho nó theo chương trình. Những gì tôi đã nói là khi bạn đặt nó trong trình xây dựng giao diện, nó tạo ra ràng buộc chiều rộng và chiều cao. Tôi không bảo bạn tạo nó qua IB. Để làm điều tương tự theo lập trình, bạn phải tạo nó như view.widthAnchor.constraint(equalTo: view.heightAnchor, multiplier: aspectRatio, constant: 0)vậy
Gunhan
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.