2014-10-22 20 views
16

Önceden belirttiğim görünür efekti elde ettiğimi söylemeliyim ama şu anda tatmin edici bir şekilde değil, şu anda kısıtlamaların yerine "kırılmış" olması gerekiyor düzgün bir şekilde güncellendi.Görünüm, otomatik düzen kısıtlamaları program aracılığıyla değiştirildikten sonra güncellenmiyor

UITableView tutan bir ViewController var. Bu tableView'un yüksekliği, tuttuğu satır sayısı ne olursa olsun 0'dan (görünmeyebilir) değişebilir. Yükseklik, mevcut satır sayısını satırın yüksekliğiyle çarparak ViewController'ın viewDidLoad() 'ında hesaplanır.

Denediğim ilk şey, film şeridinde ayarlanan yükseklik kısıtlamasına bağlı bir @IBOutlet weak var tableHeightConstraint: NSLayoutConstraint! oluşturmaktı. Sadece bazı rasgele başlangıç ​​yüksekliğine sahiptir ancak gerekirse görünümü günceller yöntemle takip ViewController en viewDidLoad() içinde doğru değere güncellenir:

tableHeightConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: calculatedTableViewHeight) 

// At this point I've tried a variety of methods like the following two but actually none has worked for me 
view.layoutIfNeeded() 

// or 
view.updateConstraints() 

// or 
view.layoutSubviews() 

... ve tableView hatta aynı yöntemler sadece emin olmak için bunun yerine tüm bunları viewDidLayoutSubviews() içine koyarak.

Bundan sonra denediğim, yukarıdakiyle aynı kısıtlamayı oluşturmaktı, ancak güncelleştirme yerine yalnızca şu görünüme ekledim: view.addConstraint(tableHeightConstraint). Bu aslında istenen görsel etkiye sahipti, ancak kütüklerde bu iki yükseklik kısıtlaması ile çelişen bir sonuç elde ettim. Amacım doğru ve temiz bir kod elde etmek olduğu için denemeye devam ettim. Bu kez, ayarlanmış olanı tekrar eklemeden önce ilk önce görünümü kısıtlamadan kaldırdım. Görme, yine, her şey mükemmeldi ama hala çelişen kısıtlamalardan kurtulmadım.

Bu yüzden asıl sorum şu ki (şu ana kadar yaptığım yanlışın yanı sıra) - mevcut bir kısıtlamayı, daha sonra herhangi bir noktada görünümün ve alt görünümlerinin uygun bir güncelleme/aktarımının ardından nasıl yapabilirim Bir görünümü ilk yüklediğimde veya kullanıcı etkileşimde olduğunda bazı kısıtlamaları değiştirmek istediğimde. Herhangi bir yardım için çok teşekkürler!

+0

Özelliğin yeni bir kısıtlamaya ayarlanması eskisini kaldırmaz, yalnızca işaretçinizi yeni bir noktaya işaret eder, bu yüzden çakışan kısıtlamalar alırsınız. Cevap olarak @cmyr ile yapmalısınız. – rdelmar

+0

@rdelmar Tamam, anladım, bu açıklama için teşekkürler! Fakat view.removeConstraint (tableHeightConstraint) 'e giderken, yeni bir tane oluşturarak ve view.addConstraint (tableHeightConstraint)' ile görüntüye tekrar eklerken neden hala bir çatışma vardı? Sadece nedenleri anlamak için ... –

+1

Bu ifadede görünüm nedir? Kontrolörün kendi görüşü nedir? Hikaye panosunda yaptığınız bir yükseklik kısıtlaması, yüksekliğini ayarladığınız görünümde, tablonuzdaki tablo görünümünü (süper görünümde değil) eklenir. Denedim mi, self.tableView.removeConstraint (tableHeightConstraint)? Yeni olan tablo görünümüne de eklenmelidir. – rdelmar

cevap

29

Şu anda, geçerli olanı güncelleştirmek yerine yeni bir kısıtlama atayacaksınız. Yeni kısıtlama da görünüm hiyerarşisine eklenmedi.

Eğer IB kurulmuş bir kısıt iyi bir yaklaşım olmakla birlikte, bunun yerine var yeni bir kısıt atama, sadece kısıt sabiti değiştirmeniz gerekir başvurmak için bir IBOutlet kullanmanın Kişisel yaklaşım:

tableHeightConstraint.constant = calculatedTableHeight.

Düzenlemeler, sabitlerini değiştirdiğinizde otomatik olarak bir düzen geçişini çağırmayı ele aldığından, layoutIfNeeded() öğesini çağırmanıza gerek yoktur. updateConstraints() ve layoutSubviews() kesinlikle istediğiniz gibi değildir.

+0

Sadece 2 mod arasında daha zarif bir şekilde geçiş yapmak için işaretçiyi farklı bir kısıtlama referansı olarak değiştirmeyi gerçekten çok isterim. Ancak, herhangi bir güncelleme mesajının, yeni referans alınan kısıtlamanın bir öncekinin yerine geçmesine neden olacağı görülmemektedir. Modları değiştirmek istediğimde söz konusu kısıtlamaları eklemek ve kaldırmak zorunda kaldım mı? – Michael

+0

@Michael: Kısıtlamayı yaptığınız referans kendi kullanımınız içindir; Bir görünüme bir kısıtlama eklerseniz ve herhangi bir yere herhangi bir referans kaydetmezseniz, yine de görünüme eklenir. – cmyr

+0

Evet, mantıklı; Kısıtlamaların sadece bir dizi öğe olarak göründüğünü anladığınızda daha kolay anlaşılır. Bir IBOutlet'e bağlı bir XIB kısıtlaması, kısıtlamayı ilklendirmek ve ilk yüklemede diziye eklemek için bir yoldur. Denetleyicinizdeki işaretçiyi değiştirmek, dizide olanı değiştirmez, kısıtlamadaki bir özelliği (yani sabit) değiştirmek bir değeri değiştirir ve gerçek bir etkiye sahiptir. – Michael