Bagaimana cara memperbarui batasan ketinggian konstan dari UIView secara terprogram?

102

Saya memiliki UIViewdan saya mengatur batasan menggunakan Xcode Interface Builder.

Sekarang saya perlu memperbarui UIView'sketinggian itu secara konstan secara terprogram.

Ada fungsi yang seperti itu myUIView.updateConstraints(), tapi saya tidak tahu bagaimana menggunakannya.

Chris Mikkelsen
sumber
Ambil jalan keluar dari batasan ketinggian dan atur secara terprogram
iMuzahid
Anda dapat menggunakan tautan ini atau tautan ini untuk referensi.
Amna Farhan
Berikut adalah cara untuk memperbarui satu atau beberapa batasan. stackoverflow.com/a/54171693/8861442
Sarath Kumar Rajendran

Jawaban:

217

Pilih batasan ketinggian dari pembuat Antarmuka dan ambil jalan keluarnya. Jadi, saat ingin mengubah ketinggian view bisa menggunakan kode di bawah ini.

yourHeightConstraintOutlet.constant = someValue
yourView.layoutIfNeeded()

Metode updateConstraints()adalah metode contoh UIView. Ini berguna saat Anda menyetel batasan secara terprogram. Ini memperbarui batasan untuk tampilan. Untuk lebih jelasnya klik disini .

Parth Adroja
sumber
58
Hari ini saya belajar bahwa Kendala dapat diubah menjadi jalan keluar, dan dari sana saya dapat melakukan apa pun yang ingin saya lakukan dengannya. Terima kasih
Chris Mikkelsen
@ParthAdroja, sobat bisa lihat pertanyaan saya stackoverflow.com/questions/46034278/… ?
Mei Phyu
Saya tidak memiliki file xib, dan bagaimana mengatur yourHeightConstraint di UIView secara terprogram?
Newszer
@newszer Anda perlu melihat topik lain untuk stackoverflow.com/questions/31651022/…
Parth Adroja
Saya mendengar bahwa kita harus memanggil layoutIfNeeded setelah mengubah batasan konstan. Mengapa? dan terkadang saya memanggil layoutIfNeeded di dalam viewWillLayoutSubviews dan viewDidLayoutSubviews. apakah ini oke
mnemonic23
104

Jika Anda memiliki tampilan dengan banyak batasan, cara yang jauh lebih mudah tanpa harus membuat banyak outlet adalah:

Dalam pembuat antarmuka, berikan setiap batasan yang ingin Anda ubah pengenalnya:

masukkan deskripsi gambar di sini

Kemudian dalam kode Anda dapat memodifikasi beberapa batasan seperti:

for constraint in self.view.constraints {
    if constraint.identifier == "myConstraint" {
       constraint.constant = 50
    }
}
myView.layoutIfNeeded()

Anda dapat memberikan beberapa batasan pada pengenal yang sama sehingga memungkinkan Anda untuk mengelompokkan batasan dan mengubah semuanya sekaligus.

George Filippakos
sumber
Ini berfungsi dengan baik tetapi saya merasa lebih mudah menggunakan hanya koleksi outlet biasa untuk mengelompokkan kendala. Misalnya, pada tampilan yang saya kerjakan ada 47 kendala tetapi hanya 6 yang ingin saya ubah saat runtime sehingga loop yang jauh lebih kecil. Ini juga tidak memerlukan sinkronisasi string antara dua tempat yang berbeda.
Gary Z
1
Terima kasih George untuk tip ini. Ini adalah bantuan nyata dengan beberapa tata letak saat ini yang saya mainkan.
Jim Hillhouse
1
INDAH
William Yang
Hai, Saya menggunakannya dengan cara yang sama, tetapi tidak pernah masuk dalam kasus if dan saya telah memberikan pengenal yang sama.
Rob13
Saya bertanya-tanya apakah mungkin untuk menyebutkan kendala. Jawaban yang bagus!
ShadeToD
35

Berubah HeightConstraintdan WidthConstraintTanpa membuat IBOutlet.

Catatan: Tetapkan batasan tinggi atau lebar di Storyboard atau file XIB. setelah mengambil Batasan ini menggunakan ekstensi ini.

Anda dapat menggunakan ekstensi ini untuk mengambil Batasan tinggi dan lebar:

extension UIView {

var heightConstraint: NSLayoutConstraint? {
    get {
        return constraints.first(where: {
            $0.firstAttribute == .height && $0.relation == .equal
        })
    }
    set { setNeedsLayout() }
}

var widthConstraint: NSLayoutConstraint? {
    get {
        return constraints.first(where: {
            $0.firstAttribute == .width && $0.relation == .equal
        })
    }
    set { setNeedsLayout() }
}

}

Kamu bisa memakai:

yourView.heightConstraint?.constant = newValue 
AshvinGudaliya
sumber
2
Ada metode first(where: ...)yang dapat Anda gunakan segera daripada filter+first
Vyachaslav Gerchicov
13

Seret batasan ke VC Anda sebagai IBOutlet. Kemudian Anda dapat mengubah nilai terkait (dan properti lainnya; periksa dokumentasi):

@IBOutlet myConstraint : NSLayoutConstraint!
@IBOutlet myView : UIView!

func updateConstraints() {
    // You should handle UI updates on the main queue, whenever possible
    DispatchQueue.main.async {
        self.myConstraint.constant = 10
        self.myView.layoutIfNeeded()
    }
}
dylanthelion.dll
sumber
9

Anda dapat memperbarui batasan Anda dengan animasi yang halus jika Anda mau, lihat potongan kode di bawah ini:

heightOrWidthConstraint.constant = 100
UIView.animate(withDuration: animateTime, animations:{
self.view.layoutIfNeeded()
})
Hafiz Muhammad Farooq Rasheed
sumber
4

Jika metode di atas tidak berhasil maka pastikan Anda memperbaruinya di blok {} Dispatch.main.async. Anda tidak perlu memanggil metode layoutIfNeeded () kemudian.

Nupur Sharma
sumber
4

Pertama hubungkan kendala Ketinggian ke viewcontroller kami untuk membuat IBOutlet seperti kode di bawah ini yang ditunjukkan

@IBOutlet weak var select_dateHeight: NSLayoutConstraint!

kemudian letakkan kode di bawah ini dalam tampilan tidak memuat atau di dalam tindakan apa pun

self.select_dateHeight.constant = 0 // we can change the height value

jika di dalam klik tombol

@IBAction func Feedback_button(_ sender: Any) {
 self.select_dateHeight.constant = 0

}
Nimisha joshy
sumber
1

Untuk memperbarui batasan tata letak, Anda hanya perlu memperbarui properti konstanta dan memanggil layoutIfNeeded setelahnya.

myConstraint.constant = newValue
myView.layoutIfNeeded()
Fran Martin
sumber
1
Create an IBOutlet of NSLayoutConstraint of yourView and update the constant value accordingly the condition specifies.

//Connect them from Interface 
@IBOutlet viewHeight: NSLayoutConstraint! 
@IBOutlet view: UIView!

private func updateViewHeight(height:Int){
   guard let aView = view, aViewHeight = viewHeight else{
      return
   }
   aViewHeight.constant = height
   aView.layoutIfNeeded()
}
CrazyPro007
sumber