Bagaimana cara membuat persentase lebar total menggunakan autolayout?

114

Saya perlu membuat tiga kolom dinamis, masing-masing dengan persentase tetap dari total lebar. Bukan pertiga, tapi nilai yang berbeda. Misalnya, ilustrasi berikut memperlihatkan tiga kolom: yang pertama lebar 42%, yang kedua lebar 25%, dan yang ketiga lebarnya 33%.

Untuk 600 piksel di seluruh viewcontroller, itu akan menjadi 252, 150, dan 198 piksel.

Namun demikian, untuk ukuran tampilan berikutnya (yaitu iPhone 4 lanskap (lebar 960) atau potret iPad 2 (lebar 768), saya ingin persentase relatifnya sama (bukan lebar piksel yang dikutip di atas).

Apakah ada cara untuk melakukan ini dengan menggunakan Papan Cerita (yaitu tanpa kode)? Saya dapat melakukan ini dengan mudah dalam kode, tetapi tujuan saya adalah memasukkan sebanyak mungkin logika tampilan ini ke dalam Storyboard.

masukkan deskripsi gambar di sini

Jeffrey Berthiaume
sumber

Jawaban:

205

Jika, seperti yang Anda katakan, Anda tahu cara melakukannya dalam kode, maka Anda sudah tahu cara melakukannya di papan cerita. Ini persis batasan yang sama, tetapi Anda membuatnya secara visual daripada dalam kode.

  1. Pilih tampilan dan tampilan supernya.

  2. Pilih Editor -> Pin -> Widths Sama-sama untuk membatasi lebar agar sama dengan lebar tampilan super (sebenarnya dialog munculan "pin" di bagian bawah kanvas berfungsi paling baik di sini).

  3. Edit batasan dan atur Pengali ke pecahan yang diinginkan, misalnya 0,42. Begitu pula untuk pandangan lainnya.

Matt
sumber
9
Pastikan bahwa tampilan yang Anda batasi muncul di "item pertama" dari Equal Widths Constraint dan bukan lebar tampilan super, jika tidak, Anda membuat kelipatan lebar subview Anda dari lebar tampilan super. Saat mengontrol-menyeret dari subview ke superview untuk menerapkan batasan lebar yang sama, ini selalu terbalik, yang tampaknya kontra-intuitif bagi saya.
memmons
Ah - dengan "melakukannya dalam kode" yang saya maksud adalah "secara manual, tanpa batasan atau tata letak otomatis".
Jeffrey Berthiaume
Jawaban bagus. Saya heran IB tidak menyediakan cara melakukan ini tanpa mengedit kendala.
wcochran
Saya mencoba menerapkan ini di UITableViewCell saya dan semuanya berwarna abu-abu. Saya harus menyematkan semua pandangan saya dalam tampilan baru dan memilih Lebar Sama dari label saya ke tampilan baru ini. Semoga membantu.
nano
6
Baru di Xcode7: Jika Anda ingin meratakan tampilan, gunakan "Stack View" yang baru.
Bijan
15

Saat Apple memperkenalkan UIStackView, ini membuat pekerjaan menjadi lebih mudah.

Metode 1: Menggunakan Nib / StoryBoard:

Anda hanya perlu menambahkan tiga tampilan di pembuat antarmuka & menyematkannya ke dalam stackview

Xcode ► Editor ► Sematkan ► StackView

masukkan deskripsi gambar di sini

Pilih stackView & berikan batasan dengan leading, trailing, top & equal height dengan safeArea

Klik untuk Atribut area inspektur & Setel StackView horizontal & distribusi untuk mengisi secara proporsional

[ masukkan deskripsi gambar di sini3

Beri pembatas tiga tampilan dengan leading, trailing, top, bottom dengan masing-masing sisi. masukkan deskripsi gambar di sini

Metode 2: Secara terprogram:

import UIKit
class StackViewProgramatically: UIViewController {
    var propotionalStackView: UIStackView!
    ///Initially defining three views
    let redView: UIView = {
        let view = UIView()//taking 42 % initially
        view.frame = CGRect(x: 0, y: 0, width: 42 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .red
        return view
    }()

    let greenView: UIView = {
        let view = UIView()//taking 42* initially
        view.frame = CGRect(x: 42 * UIScreen.main.bounds.width/100, y: 0, width: 25 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .green
        return view
    }()
    let blueView: UIView = {
        let view = UIView()//taking 33*initially
        view.frame = CGRect(x: 67 * UIScreen.main.bounds.width/100, y: 0, width: 33 * UIScreen.main.bounds.width/100, height: UIScreen.main.bounds.height)
        view.backgroundColor = .blue
        return view
    }()

    ///Changing UIView frame to supports landscape mode.
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        DispatchQueue.main.async {
            self.redView.frame = CGRect(x: 0, y: 0, width: 42 * self.widthPercent, height: self.screenHeight)
            self.greenView.frame = CGRect(x: 42 * self.widthPercent, y: 0, width: 25 * self.widthPercent, height: self.screenHeight)
            self.blueView.frame = CGRect(x: 67 * self.widthPercent, y: 0, width: 33 * self.widthPercent, height: self.screenHeight)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        //Adding subViews to the stackView
        propotionalStackView = UIStackView()
        propotionalStackView.addSubview(redView)
        propotionalStackView.addSubview(greenView)
        propotionalStackView.addSubview(blueView)
        propotionalStackView.spacing = 0
        ///setting up stackView
        propotionalStackView.axis = .horizontal
        propotionalStackView.distribution = .fillProportionally
        propotionalStackView.alignment = .fill
        view.addSubview(propotionalStackView)
    }
}
//MARK: UIscreen helper extension
extension NSObject {

    var widthPercent: CGFloat {
        return UIScreen.main.bounds.width/100
    }

    var screenHeight: CGFloat {
        return UIScreen.main.bounds.height
    }
}

Keluaran:

Bekerja dengan lanskap & potret

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Proyek demo - https://github.com/janeshsutharios/UIStackView-with-constraints

https://developer.apple.com/videos/play/wwdc2015/218/

Mendongkrak
sumber
4

Saya rasa ini bisa dijelaskan lebih detail sehingga bisa lebih mudah diterapkan ke sejumlah tampilan yang membutuhkan tata letak persentase tetap dalam superview.

Tampilan paling kiri

  • Berlabuh ke SuperView.Leading
  • Mendefinisikan persentase tetapnya sebagai pengali di SuperView.Height

Tampilan menengah

  • Mendefinisikan persentase tetapnya sebagai pengali di SuperView.Height
  • Pin leftke kanan tetangganya

Tampilan Paling Kanan

  • Tidak menentukan persentase tetap (ini adalah sisa dari tampilan yang tersedia)
  • Pin leftke kanan tetangganya
  • Pin itu rightkeSuperView.Trailing

Semua Tampilan

  • Tentukan ketinggian tidak tetapnya dengan menambatkan ke Top Layout Guide.Topdan Top Layout Guide.bottom. Dalam jawaban di atas, perlu dicatat bahwa hal ini juga dapat dilakukan dengan mengatur ketinggian yang sama ke pandangan tetangga.
JuJoDi
sumber