En boy oranı sınırlamalarını iOS'ta programlı olarak nasıl ayarlayabilirim?


85

Görünüm denetleyicilerim için otomatik düzen kullandım. V ve H konumlarını kısıtlamalarda ayarladım, ancak düğme boyutumu 5s, 6 ve 6 Plus olarak değiştiğinde nasıl artırabileceğimi bilmek istiyorum. Giriş düğmesi için kısıtlamaları bu şekilde ekledim:

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];

Ama benim sorunum, sol ve sağ taraf boşluğunu yönetirken, yükseklik sabit olduğu için iPhone 6 ve 6 Plus'ta geriliyor. Ekran boyutuna göre boyutu nasıl artırabilirim? Bunun en boy oranı olabileceğini düşünüyorum, ancak kodda en boy oranı kısıtlamasını nasıl ayarlayabilirim?


Yanıtlar:


84

Bunun gibi. Bir kere dene.

[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]];

veya (self.yourview.frame.size.height / self.yourview.frame.size.width)sizin yerinize herhangi bir float değeri kullanabilirsiniz. Teşekkürler.

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))

Bana bu hatayı veriyor 'NSInternalInconsistencyException' yakalanmamış istisna nedeniyle uygulamayı sonlandırıyor, nedeni: 'Çarpan sonlu değil! Bu yasadışı. çarpan: nan '
IRD

2
Bu senaryoda, örneğin yükseklik 100, genişlik 200 ise ve kodumla 0,5 çarpanı verdiyseniz, boyunuz başka bir kısıtlamayı değiştirerek 150'ye çıkacaksa genişlik otomatik olarak 300'e çıkacaktır. Ancak bunu yapmak için ihtiyacınız var. genişlik veya yükseklik gibi görünümün bir kısıtlamasını artırmak için.
Mahesh Agrawal

1
yüksekliği alacak: genişlik = 1: 2 yani 0.5.
Mahesh Agrawal

3
Programatik olarak herhangi bir kısıtlama belirlemeden önce bu satırı eklemeyi unutmayın: [self.yourview setTranslatesAutoresizingMaskIntoConstraints:NO];
atulkhatri 01

1
Kısıtlamaları kullanırken, çerçeve boyutlarımın tümü sıfırdı. En boy oranını elde etmek için bunun yerine kullandımself.yourview.intrinsicContentSize
Phlippie Bosman

89

Düzen Bağlantıları , kısıtlamaları programlı olarak ayarlamanın en uygun yoludur.

Düğmeniz için 5: 1 en boy oranı ayarlamak istediğinizi varsayalım, o zaman şunu kullanmalısınız:

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

İşte tam kod:

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
    }

}

İşte yukarıda yazılı kodla elde edilen sonuçlar. Bu düğmenin çeşitli cihazlarda 5: 1 en boy oranını koruduğunu görebilirsiniz:

Sonuç görünümü


14

Swift 3:

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

1
İOS 8 ve üzeri için addConstraint (:) çağırmak yerine NSLayoutConstraint'in isActive özelliğini kullanmanız gerekir. aspectRatioConstraint.isActive = true
dvdblk

Neden .widthilk özellik olarak kullanmıyorsun ? Sonucudur attr2 * multiplier boy oranı, width / heightbu yüzden, width = height * aspectRatiobiz koyarsanız, .heightbirinci özellik ve aspectRatiohiç multiplierardından sonuç tamamen tersine çevrilir.
Kimi Chiu

13

Arayüz Oluşturucu'da Tasarım zamanında "Yükseklik kısıtlaması" ayarlayabilirsiniz. "Derleme zamanında kaldır" ı işaretlemeniz yeterlidir ve Uygulama çalışacağı zaman kaldırılır.

görüntü açıklamasını buraya girin Bundan sonra, örneğin viewDidLoad yönteminde "En Boy Oranı" kısıtlaması ekleyebilirsiniz.

Xamain.iOS'ta "16: 9" şu şekilde görünür:

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

Veya Mahesh Agrawal'ın dediği gibi:

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

12

UIView'de Yardımcı Uzantı

extension UIView {

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

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

Ve kullanım:

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


and usage: view.aspectRation (1.0 / 1.0)
Michał Ziobro

1
Bu gerçekten de birkaç türü yasaklayan zarif bir çözümdür: 1. toItem parametresi 2 .selfyerine olarak ayarlanmıştır self. Ve açıklamadaki kullanım view.aspectRation(1.0/1.0).isActive = true bunu Xcode 10.2.1 Swift 5'te test etmeliyim .
Pankaj Kulkarni

3

Yukarıdaki tüm cevapları denedim ama işe yaramadı ve bu benim hızlı 3 ile çözümüm:

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()

Otomatik düzen hatalarını önlemek için yenilerini eklemeden önce kısıtlamaları her zaman devre dışı bırakmalısınız (potansiyel olarak çakışan)
John

0

Görünümler için kısıtlamalar ve ayrıca özellikler vardır.

en boy oranları, görünümün bir özelliğidir , bu nedenle onu içerik modunu kullanarak ayarlayabilirsiniz.

imageView.contentMode = .scaleAspectFit

bu, bir görünümün oranları değiştirmemesini sağlayacaktır, örneğin

  • yükseklik veya genişlik ekrana sığacak olandan daha büyük
  • yükseklik sabit olarak kodlanmıştır ve bu nedenle farklı ekran boyutlarına uyum sağlayamayacaktır.

Soru ImageView ve içerik modu ile ilgili değil, otomatik düzen ve kısıtlamalarla ilgili. Arabirim Oluşturucu'dan, sonunda bir çarpanla genişlik-yükseklik kısıtlaması oluşturan en boy oranı kısıtlamasını ayarlayabilirsiniz.
Gunhan

@ Gunhan soru programatik olarak nasıl ayarlanacağıyla ilgili. Arayüz oluşturucuda ayarlayabilmeyi bilmek güzel, ancak bu soru ile alakasız.
valeriana

Sanırım daha önce söylediklerimi yanlış anladınız. Bu soruda kimse ImageView hakkında konuşmuyor. BT, otomatik düzen ve kısıtlamalarla ilgilidir ve bunu programlı bir şekilde yapmak zorundadır. Arayüz oluşturucuda ayarladığınızda genişlikten yüksekliğe bir sınırlama yarattığını söylemiştim. IB aracılığıyla oluşturmanızı söylemedim. Programlı aynı şeyi yapmak için gibi oluşturmak zorunda view.widthAnchor.constraint(equalTo: view.heightAnchor, multiplier: aspectRatio, constant: 0)böylece
Gunhan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.