Stack View — Hugging ve Compression Resistance Priority Kullanımı

Yunus Tek
Yunus Tek
Dec 4, 2018 · 6 min read

Merhaba, Bu yazıda Compression Resistance ve Hugging priority konusunu ele alıyoruz. Tüm cihazlarda tekil görünümü yaratmak söylendiği kadar zor mu? Cevabı birlikte inceledikten sonra siz verin. Hadi başlayalım.

Image for post
Image for post

Stack View Nedir?

Image for post
Image for post

Autolayout oluşturmada zorlandığımız noktalarda hızlı çözüm sağlayan StackView iOS 9 ile hayatımıza girdi.

Image for post
Image for post

Sağ tarafta gösterilen Stack View’in property’lerinin içindeki objeleri nasıl etkilediklerine şöyle değineyim:

1) Axis

Yatay veya dikey olarak hizalama yapmanızı sağlar:

Image for post
Image for post

2) Alignment

Axis durumuna göre aşağıdaki şekillerde hizalama yapmanızı sağlar;
Axis Vertical durumu için: Leading, Training, Fill ve Center
Axis Horizontal durumu için: Top, Buttom, Fill ve Center

Image for post
Image for post

3) Distribution

Aşağıdaki kuralları belirleyerek boyut dağılımını yapmanızı sağlar:

Fill: Yeni bir UIStackView oluşturulduğunda varsayılan dağıtım türü olarak belirlenir. Benim test örneğimde, doldurma için UITextField ve UIImageView kullandım ve bunları yatay bir UIStackView görünümünde gruplandırıyorum.
Kontrollerinizi, Distribution ı Fill olarak ayarlanan bir UIStackView içerisine yerleştirdiğinizde, kontrollerin tümünü doğal boyutlarında tutacak ve alanı doldurmak için bunlardan birini uzatacaktır. Hangisinin en düşük Content Hugging Priority (CHP) sahip olduğuna dikkat ederek hangi kontrolün uzatılacağını belirler. UITextField’ları arasına sekiz birim boşluk ekledim, böylece her birinin boyutunu görebilirsiniz.

Image for post
Image for post

Tüm kontrolleriniz aynı CHP’ye sahip ise Xcode, düzenin belirsiz olduğunu şikayet eder. Düzeltebilmek için stackview içerisindeki objelerin boyutları belli olmalı veya ekranın boyutunun yetersiz kalması durumunda önceliğin kimde olduğu belirtilmelidir.

Örneğin üstteki görselde 3 objeden sadece iki objenin genişliği bellidir üçüncü objenin hugging’i low olduğundan geri kalan kısımı o kaplamış.

Başka bir örnek, iki textfield’ın hugging’i high ise bunlar daralacak üçüncü textfield’ın hugging’i low olduğu için kalan alanı bu textfield dolduracaktır.

Sonuç olarak stackview içindeki nesneler kendi özelliklerini (genişlik, yükseklik, hugging veya compression değerleri) baz alarak stackView’i tam olarak doldurmak zorundadırlar.

Fill Equal : Bu tür ile, UIStackView in her kontrol eşit büyüklükte olacaktır. Mümkünse kontroller arasındaki boşluğun tamamı kullanılacaktır. Bu türle CHP’nin önemi yoktur, çünkü her kontrol aynı boyuttadır.

Image for post
Image for post

Fill Proportionally : Bu tür keşfetmek için eğlencelidir :) Farklı telefon boyutları ve yönelimleriyle oynayıncaya kadar bu türün etkisini görmek zor. UIStackView, size’ınız büyüyüp küçüldükçe, kontrollerin birbiriyle orantılı olarak aynı oranda boyutlanmasını sağlar. Testimi UITextField’lar yerine UILabel kullanarak değiştirdim.

Image for post
Image for post

Dağılımın portrait ve landscape için görünümü şu şekildedir:

Image for post
Image for post
Image for post
Image for post

Gördüğünüz gibi, farklı düzen boyutları için imageView ve label’ların oranları korunur.

Equal Spacing : Bu dağıtım türü, kontrollerin her biri arasında eşit aralık bırakacak ve kontroller kendisini yeniden boyutlandırmayacaktır. Bunu, etiketler ve görüntüler arasındaki boşluğun eşit boyutunu belirtmek için kırmızı çizgiler çizerek gösterdim.

Image for post
Image for post

Equal Centering : Son olarak, son dağıtım türünün bir örnek olmadan görmesi biraz zor. Kontrollerin merkezlerini eşit olarak uzatacaktır. Bunu göstermek için, her bir kontrolün merkezine kırmızı dikey çizgiler çizdim. Kırmızı çizgiler arasındaki mesafe eşit aralıklarla yerleştirilir.

Image for post
Image for post

4) Spacing

Aralardaki boşluğu belirler:

Image for post
Image for post

Bir UIStackView kullanırken tüm bu seçenekler birbirlerinden oldukça farklı davranırlar. Bazıları, child’ların büyüklüğünü kontrol etme hakkında görüş bildirmişlerdir, diğerleri ise, child’ların istedikleri kadar büyük olmasını ve farklı şekillerde uzamasını sağlamaya çalışmaktadır.

Priority nedir ?
Öncelikle tüm constraint ler priority özelliğine sahiptir. Interface Builder üzerinden herhangi bir constraint tanımladığınızda default olarak priority 1000 set edilir. Priority 1 ile 1000 arasında değerler almaktadır. Değer büyüklüğüne göre öncelik artar. Eğer değeri 1000 ise bu constraint zorunlu bir constraint’tir. 1 ve 999 dahil tüm priority değerine sahip constraint’ler ise optional’dır. Layout oluşturulurken, uygun koşullar altında, optional constraint ler içerisinde doğru denklem elde edilene kadar priority en yüksekten en düşüğe kadar teker teker sağlaması yapılarak denenir.

Örneğin aynı view için hem 1000 priority hem de 999 priority’e sahip iki kural olduğunu varsayalım. 1000 priority ile safe area’ya, 999 priority ile superview’e bağlı olsunuz. Safe area olan bir sürümde çalıştırıldığında 1000 priority’li kural gerçekleştirilebildiği için view, safe area’ya bağlı olarak açılacaktır. Safe area desteklenmeyen bir sürümde (<iOS 11) çalıştırıldığında ise view 1000 priority’li kuralı gerçekleştiremediği için bir sonraki kuralın olup olmadığını kontrol edecek. 999 priority’li kural superview’e bağlı olarak tanımlandığı için bunu gerçekleştirerek view’i bu sürüm için superview’e bağlayacaktır.

UILayoutPriority’nin 4 adet priority seviyesi şöyledir :

Low (250)
Medium (500)
High (750)
Required (1000)

Intrinsic Content Size
Bazı view’lar içeriğine göre kendiliğinden bir boyuta sahiptir. Bunu onların intrinsic content size’ı olarak adlandırılıyor. UIButton ve UILabel buna bir örnektir. İkisinde de içerik olarak bulunan title’a ek olarak ufak marginler ile boyutlandırılmaktadır. Interface Build içine bir Label atıp top ve horizontal constraint tanımı yaparsanız başka hiçbir constraint e ihtiyaç duymayacaktır.

Image for post
Image for post

Yukarıdaki örnekte view içersinde 2 adet butonum var. Soldan sağdan zorunlu constraint’ler tanımlanmış durumda ve 2'si arasında 8 point lik bir constraint bulunuyor. Ancak içeriğin boyutunu aldığından burada bir conflict oluşuyor.

Bu örnekte butonların sağında, solunda ve aralarında belli bir uzaklık olmak zorunda.

Bu conflict i çözmenin yolları:
Butonlardan birine sabit boyut verilebilir

Image for post
Image for post

Buradaki örnekte 2. butona sabit bir genişlik verdik ve birinci buton içeriği kendiliğinden sıkıştı ve constraint ortadan kalktı.

Aralarındaki boşluk Küçük Eşit ( ≤ ) olarak tanımlanabilir

Image for post
Image for post

Aradaki boşluğu 8 pointe eşit veya daha küçük olabileceğini söylediğimizde görseldeki gibi içerik boyutuna göre genişlik alan butonlar iç içe geçti.

Bunlara benzer çözümler üretmek mümkün ancak bu gibi durumlarda hangi contentin bizim için daha öncelikli olduğuna karar vermemiz lazım. Bu yüzden priority yine devreye giriyor

Image for post
Image for post

Burada karşımıza Content Hugging ve Content Compression Resistance Priority çıkıyor.

Image for post
Image for post
  • Content Hugging Priority : Sarılma
    Bu öncelik constraint ler arasında priority si büyük olanın küçük olanın içeriğine göre büyümesine izin vermiyor. Yeterli olan boyutuna sarılıyor.
  • Content Compression Resistance Priority : Sıkıştırma
    Bu öncelik ise constraintler arasında prioritysi büyük olanın kendi uygun boyutunu korumak için küçük olanı sıkıştırabilmesini sağlıyor.

Peki tüm bunların bizim örneğimiz ile ne alakası var ?

Image for post
Image for post

En başa dönecek olursak şöyle bir conflict alıyoruz. Buradaki hatanın tam sebebi 2 butonun da Content Compression Resistance (CCR) priority eşit olduğundan runtime da hangisinin contenti sıkıştırabileceğini anlayamamasıdır. Burada örneğin Button 2 nin Content Hugging Priority (CHP) sini daha yüksek verecek olursak sonuç şu şekilde olacaktır.

Image for post
Image for post

Görüldüğü gibi button 2 içeriği kadar boyut aldı ve button 1 e geriye kalan alan doğrultusunda içerik sıkıştırılması yapıldı. Olayı daha iyi anlamak adına birde Button 2'nin font size’ını 15 ten 23'e alıp sonucu inceleyelim:

Image for post
Image for post

Sonuç
Autolayout işlemlerinde yapmamız gereken birçok işlemi gördüğünüz gibi stackview hallediyor. Gerekli yerlerde kullanıldığında, yeni bir obje eklenmesi durumunda zaman kaybı oluşturan durumlardan kaçınılmış olunur.

Bir sonraki yazıda görüşmek üzere 🤚

Kaynaklar

Hüseyin Bagana

NSIstanbul

A publication with content filled by NSIstanbul members

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store