Yazılar

Auto Layout Kullanımı – II

Merhaba, Auto Layout serisinin ikinci dersiyle devam ediyoruz. Eğer okumadıysanız Auto Layout Kullanımı – I dersine bakmanızı tavsiye ederim.

Nispeten daha kısa kısa bir konu olan Size(Boyut) constraint lerini bir inceleyelim…

 

Size Constraints

Size Constraints bir objenin büyüklüğü ile ilgili olan kısıtlamalardır.

Yani iPhone ekranı bağımsız sağdan 20 birim, soldan 30 birim uzaklıkta konumlan demek yerine “senin uzunluğun 50 piksel, genişliğin 60 piksel olsun” demiş oluruz.

Kısacası, objenin scale etmesini istiyorsak Position Constraints, fix bir boyuta sahip olmasını istiyorsak Size Constraints kullanmalıyız.

Tabiki pozisyon kısıtları boyut kısıtlarından daha iyidir veya kötüdür diye bir şey yok. Hepsinin kullanılması gereken durumlar birbirinden farklı olabilir. Hepsine ihtiyacımız var.

Şimdi buna bir senaryo düşünelim…

Mesala kullanıcı profili sayfamız var ve burda kullanıcının profil resmini göstereceğiz ama istiyoruzki bu resim 100×100 boyutunda olsun; ekranın büyüklüğüne göre küçülüp büyümesin.

Bu durumda size constraint i kullanmamız gerekecek.

Örneğin,

Şekildeki gibi bir View oluşturalım ve constraints penceresini açalım.

 

Kırmızı çizgiyle işaretlediğim alandan size constraint lerini ayarlayacağız.

Width ve Height olarak 100×100 verelim ve Add Constraints butonuna tıklayalım.

 

Ee verdik de hiçbir şey değişmedi. Üstelik her tarafı kırmızı çizgi oldu. Nasıl iş bu?

Sevgili Xcode diyorki “Kardeş sen bunun boyutunu ayarladın da ben bunu ekranın neresine koycam?”

Evet işte sorun bu. Yani bir objenin boyutunu ayarlamak yetmiyor. Bir de nereye yerleştireceğimizi belirtmemiz gerekiyor.

 

Şimdi objenin konumunu ayarlamak üzere constraints penceresini bir daha açalım.

 

Şekildeki gibi Top ve Leading constraint olarak 30 birim boşluk bırakırsak objenin sol üst köşede belirttiğimiz uzunlukta konumlandığını göreceğiz.

 

Xcode şimdi mutlu çünkü artık objeyi nereye ve hangi boyutta koyacağını biliyor.

 

Bazı hatalar…

 

Hadi şimdi yanlış bir şeyler yapalım.

Objenin constraint lerini böyle ayarlamışken bi de şöyle bir şey dersek nasıl olur: “Hacı sen bi de sağdan uzaklığını 40 yap bakıyım şunun”.

 

Xcode yapar yapmasına ama bir sürü de sorun yaratır…

 

Ne oldu şimdi?

Her şeyi berbat ettik.

Peki niye?

Çünkü biz en başta dedik ki bu obje 100×100 boyutunda olsun. Şimdi diyoruzki “Sen hem 100×100 boyutunda ol hemde ekranın sağına doğru genişle bakayım”.

Xcode da diyorki “Sen daha ne istediğini bilmiyorsun. Objenin boyutunu fix mi istiyorsun? Yoksa ekranın sağına doğru uzamasını mı? Ben napayım kafam karıştı”.

İşte hatayı bu yüzden alıyoruz.

Biz constraint verirken aynı zamanda diğer constraint leri bozmamamız gerekiyor. Bozarsak böyle hata alırız, Xcode ne yapacağını bilmez.

 

Neyse herkes hata yapabilir. Hata varsa çözümü de var. Biz geçmişi unutalım ve önümüzdeki güzel günlere bakalım 🌈

 

Çözüm

 

Obje seçiliyken Size Inspector’u açalım. Biraz aşağıda Constraints başlığını altında verdiğimiz constraint leri göreceğiz.

Kırmızı ile çizdiğim alan en son eklediğimiz hataya sebep olan constraint.

Hatayı düzeltmek için yapabileceğimiz iki şey var:

– Ya kırmızı ile işaretlediğim constraint i kaldıracağız ve objenin boyutu 100 x 100 şeklinde kalacak,

– Ya da width(genişlik) olarak 100 olarak verdiğimiz kısıtı kaldıracağız. Böylece objenin uzunluğu sabit kalacak ve genişliği ekrana göre relative olacak.

 

İki kıza birden aşık olmuyacağız, ikisinden birini tercih etmemiz lazım. 😁

Biz son eklediğimiz Trailing constraint ini seçelim ve Geri tuşuyla silelim.

Şimdi her şeyin eski haline geldiğini göreceğiz.

 

 

 

Size Constraints ile ilgili şimdilik bu kadar yeterli diye düşünüyorum. Örnek projenin kaynak koduna buradan erişebilirsiniz.

Serinin devamında Alignment Constraints konusunu anlatacağım.

 

Vakit ayırıp okuduğunuz için teşekkür ederim.

 

İyi kodlamalar 💻

 

 

 

Auto Layout Kullanımı – I

Uygulamaların hem dikey hem yatay pozisyonda, hem de farklı cihaz boyutlarında nasıl bozulmadan çalıştığını hiç merak ettiniz mi? Auto Layout ile bunu halledeceğiz!

Maalesef bu işler kendi kendine olmuyor. Her farklı iPhone modeli için objelerin dikey ve yatay pozisyonda nasıl konumlanacağını ayarlamamız gerekiyor.

Bu ders de zaten bunun için var 😎

Eskiden hayat ne güzeldi, tüm uygulamalar için tek bir ekran vardı. Ekrana sığacak mı, scale edecek mi derdi yoktu.

iPhone5 geldi mertlik bozuldu 😁

Apple yeni modelinde ekran boyutunu değiştirince haliyle objelerin yeri pozisyonu ve büyüklüğü gibi konular önemli olmaya başladı ve karşımıza Auto-Layout diye bir kavram ortaya çıktı.

Auto Layout konusu biraz ilginç bir konu çünkü konunun tam olarak oturması biraz zaman ve pratik istiyor. Tam olayı çözdüm zannediyorsunuz sonra bakıyorsunuzki her yerden kırmızı çizgiler fışkırıyor…

Bu kadar önemli bir konu hakkında da maalesef detaylı ve güzel anlatılmış bir ders de bulamadım. O yüzden ben kendi anladığım kısımları elimden geldiğince güzel anlatmaya çalışacağım.

 

Başlayalım 🔨

Auto-Layout Nedir?

1*LIAu1pZIZABu049UI-_L3Q.jpeg

Auto-Layout’u tanımlamadan önce constraint nedir onu bilmemiz gerek.

Constraint kısaca kısıt demektir. Örneğin UI dizaynı yaparken objeye derizki “Ekranın sağ köşesinden 30 birim uzakta ol.”

İşte burada “sağdan 30 birim uzaklık” bir kısıt, yani constraint dir.

Auto Layout ise verdiğimiz constraint lere göre ekranın bir pozisyonunda ve boyutunda durmasını sağlayan bir özelliktir.

 

Constraint ler

Türlü türlü constraint bulunmakta. Bunlardan başlıcaları:

  • Pozisyon constraint leri
  • Boyut(Size) constraint leri
  • Hizalama(Align) constraint leri

 

Pozisyon Constraint leri

Pozisyon constraint leri objenin ekrana olan uzaklığını belli etmek için kullanılır.

Örneğin beyaz renkli bir UIView objemiz var fakat ekranın sol ve sağ kenarına olan uzaklığının 50 birim, yukarı ve aşağı kenardan olan uzaklığının ise 100 birim olmasını istiyoruz.

Biz bu pozisyon constraint lerini verdikten sonra objenin görünümü belirttiğimiz şekilde değişecek ve soldan ve sağdan 50 birim kalıncaya kadar genişleyecek, aynı zamanda üstten ve alttan 100 er birim kalana kadar uzayacak. Bu istisnasız tüm iPhone cihazlarında geçerli olacak.

Obje eğer belirttiğimiz pozisyonlardan daha büyük olsaydı bu sefer de verdiğimiz kısıtlara göre küçülecekti.

Tabiki şuna dikkat etmek lazım: Verdiğimiz 50 birim aralık iPhone 8 Plus da çok bir uzaklık sayılmazken iPhone 5 ekranında daha fazla gözükecektir. Bu da uyarım olsun 🙂

 

Pozisyon constraint lerini şekildeki gibi veriyoruz.

 

Gördüğümüz gibi seçtiğimiz kenar kırmızı renkle belirginleşiyor ve hangi kenara constraint vermek istiyorsak onu belirtiyoruz.

Burada şuna çok dikkat edelim: Verdiğimiz pozisyon constraint leri default olarak kendisine komşu olan en yakın obje için verilir.

Bu örnekte başka obje olmadığı için en yakın obje self, yani ana sahnemiz oluyor. Peki ya başka obje daha olsaydı?

 

UIView altına bir TextField eklediğimizi düşünelim. Buna pozisyon constraint i vereceğiz. Bakalım hangi komşuları varmış…

TextField ın üstüne constraint koymak istediğimiz zaman 3 adet seçenek olduğunu görüyoruz.

Varsayılan olarak en alttaki View objesi seçili ve uzaklığı 34 birimmiş. Eğer Add dersek hemen yukarısındaki UIView ile arasına 34 birim mesafe koyacak.

Diğer komşuları kimmiş?

Bir tane daha View var. Bu View tüm ekranı kaplayan ana View i temsil ediyor. Aslında daha sonradan eklediğimiz View için farklı bir isim vermemiz lazım, karışıklık olmasın.

Kısaca contentView diyebiliriz.

 

Komşulara devam edelim…

Bir de Safe Area var, bu ne ola ki? 🤔

Safe Area dediğimiz ekranda kullanabileceğimiz içerik alanını temsil ediyor. Mesala bir TableView yarattınız. Bunun gidip de saat, kamera gibi cihaz fonksiyonlarını kapatmasını önlemek için böyle bir önlem almışlar. Kullanmanızı tavsiye ederim.

Ben örnekte iPhone 8 ekranı kullandığım için Safe Area ile View büyüklükleri sabit kaldı. Eğer iPhoneX kullansaydık şekildeki gibi bazı kısıtlamalara maruz kalacaktık.

Neyse,

Komşuları tanıdık, selamlaştık, bi çaylarını içtik… Sıra pozisyon constraint i eklemeye geldi.

TextField ın contentView komşusuna olan uzaklığı 30 birim olsun diyelim ve Add butonuna basalım.

 

Bunu yapar yapmaz Xcode butonun sağından solundan ince çizgiler oluşturacak. Bu eklediğimiz constraint i temsil ediyor. Yalnız sadece top constraint eklediğimiz için bazı yerlerde hata alacağız, bunu göstermek istiyorum.

 

Gördüğünüz gibi Xcode top constraint den memnun iken sağ ve sol kısımdan memnun olmadı. Neden?

Çünkü bir objenin pozisyonuna karar verebilmek için sadece top veya bottom constraint vermek yeterli değil: Objenin sağ, sol, üst ve alt pozisyonlarına teker teker constraint vermemiz gerekiyor. Yoksa objemiz ekranda istediğimiz gibi pozisyon almayacak.

İşte bu yüzden Xcode şikayetçi oldu. Dedi ki sağ ve sol köşelerde sorun var, düzelt.

Sağ ve soldaki kırmızı çizgileri anladık. Peki neden aşağıdaki kenardan şikayetçi olmadı? Aşağıya constraint vermedikki…

Çünkü, bütün objelerin pozisyon alabilmesi için dört ayrı köşeden constraint e ihtiyacı yoktur. Bazı objelere yükseklik vermek gerekirken, bazılarına sadece en-boy vermek yetebilir.

TextField için de bu durum yükseklik constraint i için geçerli. TextField Auto-Layout ile constraint vermek istediğinizde yükseklik vermeseniz de olur. Eğer yükseklik vermezseniz kendi varsayılan büyüklüğünü kullanır.

Mesala benzer bir durum Label için de geçerli. Siz Label a genişlik veya yükseklik constraint i vermek zorunda değilsiniz. Sadece dikeyde ve yatayda nereye hizalanacağını belirtmemiz yeterli ama Label ı şu anlık boş verelim.

 

Şimdi sağ ve sol kenar constraint leri vererek genişliğini ayarlayalım.

 

Add constraint der dermez Xcode sağdan ve soldan verdiğimiz 120 birim boşluk ile mutlu oldu. Gördüğünüz gibi yükseklik constraint i vermemize gerek kalmadı.

 

Peki versek ne olurdu?

Bir de bottom constraint ekleyelim o zaman…

 

Aşağıdan 20 birim boşluk bırak dediğimiz zaman TextField aşağıya doğru uzayacak. Ta ki aşağıdaki kenardan 20 birim boşluk kalıncaya kadar.

Ee bir de yukarda constraint i var bu adamın. Ne olacak? İçten dışa doğru lastik gibi uzayacak. Şöyleki…

 

Hatırlarsanız aynı işlemi contentView için yapmıştık. Ona da aynı böyle pozisyon constraint leri vererek sağından solundan uzatmıştık.

Ama bunu yapmanın bir şartı var…

Biz constraint eklerken komşu seçiyoruz değil mi? TextField a contentView den 20 birim uzakta ol derken önce contentView in pozisyonun belli olması lazım.

Biz eğer “Ali sen Mehmet’e 10 adım uzakta olcaksın. Mehmet sen de Ali’ye 10 adım uzakta olacaksın” dersek Ali ile Mehmet nerede pozisyon alacaklar? İkisi de birbirine bağımlı? Ali ile Mehmet sınıfta dikiliyorlar ama sınıfın neresinde?

Önce biz Ali’ye diyeceğizki, oğlum sen sınıfın sağ üst köşesinde duracaksın.

Artık Ali’nin pozisyonu belli. Artık şimdi Mehmet Ali’ye göre referans alabilir…

Mehmet, oğlum sen de Ali’nin 10 adım gerisinde duracaksın.

Heh. Şimdi oldu.

İşte biz de aynı şeyi yapmaya çalışıyoruz.

Biz başta contentView in pozisyonunu başarıyla belirtmemiş olsaydık herhangi bir obje contentView i referans almaya kalktığında hata ile karşılacaktı.

Biz contentView in bütün pozisyonlarını ayarladığımız için sorunla karşılaşmadık.

Şimdi contentView in bazı constraint lerini kaldıralım ve durumu bir daha inceleyelim.

Ama önce constraint çizgilerinin belli olması için arkaplan rengini değiştirelim. İkisi de mavi olduğu zaman pek belli olmuyor, ben sarı yaptım.

contentView seçili iken Size Inspector’a gelelim ve Constraints kısmına bir bakalım…

contentView için hangi constraint leri vermişisiz bir inceleyelim:

Align Trailing to: Safe Area

– Safe Area, yani ekranın sağına 50 birim uzakta ol demişiz.

Align Leading to: Safe Area

– Ekranın soluna 50 birim uzakta ol

Align Top to: Safe Area

– Ekranın üstüne 100 birim uzakta ol

Align Bottom to: Safe Area

– Ekranın altına 100 birim uzakta ol

 

 

Bir de Bottom Space to: TextField (30) diye bir alan var. Burası da contentView in alt kısmının TextField ın üst kısmına olan mesafeyi temsil ediyor.

Aslında biz böyle bir constraint i contentView içinde tanımlamadık, haklısınız fakat TextField a dedikki “Senin üst kısmın ile contentView arasında 30 birim boşluk olmuş olsun”.

Bunu dediğimiz zaman otomatik olarak TextField ın üstü, contentView in altı oluyor.

Dolayısıyla eğer Bottom Space to: TextField (30) alanını 10 yaparsak TextField ın üst kısmıyla contentView in alt kısmı arasında 10 birim boşluk olması gerektiğini söylemiş oluyoruz.

Bu sefer de TextField ın top constraint i 10 birim olacak ve bottom constraint e dokunmadığımızı farzedersek TextField yukarı doğru uzayacak.

Şöyleki,

 

Constraint lerin değerleriyle oynayabildiğimiz gibi aynı zamanda bunları tamamen kaldırabiliyoruz.

Az önce hatırlarsanız referans aldığımız objenin pozisyonunun belli olması gerekiyor yoksa problem çıkar demiştik.

Problem çıkartalım bakalım… contentView seçiliyken top constraint ini silelim.

 

Şimdi bakalım objelerin constraint leri ne hale gelmiş.

Gördüğünüz gibi TextField artık top constraint için contentView i referans alamıyor çünkü contentView in constraint leri pozisyon alabilmesi için artık yeterli değil.

TextField ın düzgün konumlanabilmesi için önce referans aldığı objenin yani contentView in düzgün konumlanabilmesi lazım ama biz bunu az önce bozduk.

contentView in constraint lerine baktığımız zaman sadece top constraint inden şikayetçi olmuyor.

Ama biz sadece top constraint ini bozmuştuk?

Evet öyle yaptık ama top constraint ini kaldırdığımız zaman contentView in pozisyonun hesaplanabilmesi için gerekli diğer alanlara da zarar verdik.

Şöyleki,

Bir objenin konumlanabilmesi için ya uzunluğunu ve genişliğini sabit yapıp (100×50) sabitleneceği bir pozisyon belirteceğiz,

ya da,

ekranın tüm köşelerinden pozisyon constraint leri vererek pozisyon belirteceğiz uzunluğu ve genişliği ekrana göre göreceli olacak.

Şimdi biz top constant i silerek uzunluğunun hesaplanmasını engelledik bu yüzden alttan ve üstten hatalarla karşılaştık. Eğer top constraint olarak tekrar bir değer girersek sorunun çözüldüğünü göreceksiniz.

 

Pozisyon constraint leri ile anlatacaklarım bu kadar. Serinin devamında diğer konuları da anlatacağım.

 

İyi kodlamalar 💻