Swift Kod İle Önyüz Tasarımı
Merhabalar bu yazımda iOS için önyüz tasarımını storyboard kullanmadan nasıl yapabileceğimizden bahsedeceğim.
Merhabalar bu yazımda iOS için önyüz tasarımını storyboard kullanmadan nasıl yapabileceğimizden bahsedeceğim.
Öncelikle storyboard gibi sürükle-bırak mantığıyla çalışan ve gayet kullanışlı bir yapı varken neden kodlama ile tasarım yaparız bundan bahsedelim.
Storyboard üzerinden tasarım yaptığımız durumlarda önyüzün yeniden düzenlenebilirlik özelliğini çok kısıtlamış olmaktayız. Örneğin projenin ileri aşamalarında ilgili önyüzde bulunan birden fazla bileşenin arasına yeni bir bileşen koyulmak istenirse, storyboard üzerinde tüm çevre bileşenler bu durumdan etkilenecek ve düzenlemesi çok zor bir hal alacaktır.
Bir diğer kodlama ile önyüz tasarımına teşvik edici sebep ise yeniden kullanılabilirlik özelliğidir. Önceki projelerimizde ortaya koyduğumuz bileşenleri bir nevi kopyala-yapıştır yöntemiyle yeni projelerimizde kullanabiliriz. İlk projelerde kodlama ile önyüz tasarlamak çok uzun ve meşakatli gözükse de bu özelliğini düşününce gelecek için çok güzel bir birikimi de yanımızda getirdiğimizi göreceğiz.
Kısaca iOS Önyüzü
iOS önyüzünde görünümlerin temeli “View”lara dayanmaktadır. “View”lar sizin belirteceğiniz boyutlarda ve konumda ekrana yerleşecektir. Bu yapıları kodlama yaparken çok kullanacağız. Bunun sebebi birden fazla önyüz bileşeninin aynı amaca hizmet ederken bir arada tutulmalarını kolaylaştırmaktır. Demek istediğimi yeniden ifade edersem bir “View” oluşturup ardından bu “View” üzerine diğer bileşenleri koyarsam elimde bir amaç uğruna birleşmiş bileşen bütünü olacaktır. Ardından oluşturduğum bu bütünü ekranda bir yere belirli bir boyutla konumlayıp tüm diğer bileşenlerin konumlarını başarıyla gerçekleştirmiş olurum.
Bir Örnek Giriş-Kayıt Ekranı Tasarımı
Sürekli teorik bilgi ile kodlama alanında tecrübe edinemeyeceğimiz ve konular havada kalmaması diye şimdi baştan bir örnek giriş-kayıt ekranı tasarımı yapalım.
Öncelikle yapmak istediğimiz ekranı sizlere göstermek istiyorum.
Şimdi tasarımı biraz inceleyelim. Görüldüğü gibi ekranda temelde 4 ana bileşen var.
- Profil fotoğrafı seçim ekranı
- Bir adet giriş-kayıt ekranını belirleyecek segment kontrolü
- Kayıt-Giriş formu
- Kayıt-Giriş butonu
Bileşenlerimizi yukarıdaki gibi belirlememiz bizim için çok önemlidir çünkü kodlama aşamasında bileşenleri konumlarken bize büyük kolaylık sağlayacaktır.
Adım adım kodlama aşamasına başlayalım.
- Form Tasarımı
Form ekranda görüldüğü gibi bileşenlerin ortasında yer almaktadır peki biz neden işe ortadan başlıyoruz? Kodlama ile arayüz tasarımında bir diğer önemli husus ta proje ilerledikçe bileşenlerin konumlarını birbirine göre vereceğimizi öngörmektir. Ben tasarımı yaparken formu ekranın ortasına koyup diğer bileşenleri ona göre yerleştirmek istediğim için öncelikle onu oluşturup ekrana yerleştirmem gerekiyor.
Not: Eğer bir bileşen başka bir bileşene göre konum alıyorsa öncelikle konum aldığı bileşeni oluşturmalısınız. Aksi halde kod işlem sırasında onu oluşturacak öğe bulunmadığı için hata alacaksınızdır.
Öncelikle form yapımızı inceleyelim. Form üzerinde görüldüğü gibi kayıt ekranında 4 giriş ekranında 2 adet olmak üzere “textField”lar bulunmaktadır. Bu “textField”lar aynı amaca hizmet edeceklerinden bir “View” içerisinde toplanmaları bize kolaylık sunacaktır.
View Kod Sınıfı Oluşturma
“View” yapımızı xCode üzerinde oluşturmak için Cocoa Touch Class tipinde bir sınıf kullanacağız.
- Öncelikle projemize “View” adında klasör oluşturalım. Bu işlemi proje klasörüne sağ tık yaparak “New Group” seçeneğini seçip yapabiliriz.
Ardından bir klasör oluşacaktır bu klasöre de “View” verelim.
- Şimdi de “View” klasörüne sağ tıklayıp “New File” seçeğini seçerek bir View sınıfı oluşturalım.
“New File”a tıkladıktan sonra gelen ekranda “Cocoa Touch Class” seçiyoruz.
Bu aşamadan sonra karşımıza sınıfımıza vereceğimiz adı ve alt sınıfını soran ekran gelecektir. Burada sınıf adını oluşturduğunuz “View”ın amacını belli edecek şekilde koymanız yararınıza olacaktır. Ben “InputContainerView” koymayı tercih ediyorum. Siz “FormView” gibi başka seçenekleri de kullanabilirsiniz. Burada asıl önemli olan kısım ise alt sınıf seçeneğidir. Biz bir “View” yaratmak istediğimizden alt sınıfımız “UIView” olacaktır.
Tüm işlemleri yaptıktan sonra View klasörünün altında yeni sınıfımız oluşmuş olacaktır. Bu sınıfa tıklayarak kod ekranına alalım. Karşımıza boş bir sınıf ekranı çıkacaktır. Oluşturduğumuz sınıf bizim seçtiğimiz şekilde “UIView” sınıfını miras edinecektir.
Artık oluşturduğumuz “View”ı kodlamaya başlayabiliriz. Tüm önyüz bileşenlerine ait nesneler kendi “init” fonksiyonları ile yaratılmaktadır. Bu sebeple öncelikle “init” fonksiyonunu yazacağız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.white //View'ın arka planını beyaz yapıyoruz self.translatesAutoresizingMaskIntoConstraints = false self.layer.cornerRadius = 5 //Köşe yarıçapı veriyoruz self.layer.masksToBounds = true //Katmanın sınırlarının kırpılmasına izin veriyoruz } |
Kod bloğunda yer alan “self.translatesAutoresizingMaskIntoConstraints = false” kodunu inceleyelim. “translatesAutoresizingMaskIntoConstraints” özelliği verilen bileşenin otomatik sınırlamalar içinde oluşup oluşmayacağını sormaktadır. Biz bileşenimize kendimiz sınırlar vereceğimizden bu değişkene “false” değerini veriyoruz.
Şimdi sıra geldi “View” üzerinde yer alacak olan “textField”ları oluşturmaya. Bu “textField”lar ayrı ayrı sınıflarda oluşturulabileceği gibi aynı sınıf içerisinde bir eleman olarak ta yapılabilir. Bizim yapımız bileşik bir yapı olacağından sınıfın elemanı olarak oluşturmamız daha gerekli gözükmektedir.
Her bir “textField”ı aşağıdaki şekilde oluşturuyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
let nameTextField: UITextField = { let textField = UITextField() //Bir textField nesnesi yaratıyoruz textField.placeholder = "Ad" //Default olarak yazı atıyoruz textField.translatesAutoresizingMaskIntoConstraints = false textField.tag = 0 return textField //çağrıldığı zaman döndürülmesini sağlıyoruz }() let surnameTextField: UITextField = { let textField = UITextField() textField.placeholder = "Soyad" textField.translatesAutoresizingMaskIntoConstraints = false return textField }() let emailTextField: UITextField = { let textField = UITextField() textField.placeholder = "E-Mail" textField.translatesAutoresizingMaskIntoConstraints = false return textField }() let passwordTextField: UITextField = { let textField = UITextField() textField.placeholder = "Şifre" textField.translatesAutoresizingMaskIntoConstraints = false textField.isSecureTextEntry = true //Parola girerken güvenli şekilde girilmesini sağlıyoruz return textField }() |
Tüm “textField”ları çağrılmaya hazır hale getirdik. Şimdi bir de “textField”lar arasına ayrıştırıcı koyalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
let nameSeperatorView: UIView = { let view = UIView() view.backgroundColor = UIColor(red: 0, green: 132, blue: 180) view.translatesAutoresizingMaskIntoConstraints = false return view }() let surnameSeperatorView: UIView = { let view = UIView() view.backgroundColor = UIColor(red: 0, green: 132, blue: 180) view.translatesAutoresizingMaskIntoConstraints = false return view }() let emailSeperatorView: UIView = { let view = UIView() view.backgroundColor = UIColor(red: 0, green: 132, blue: 180) view.translatesAutoresizingMaskIntoConstraints = false return view }() |
Sırada tüm “textField”lar ve ayrışıtırıcılar için kurulum fonksiyonu yazmaya.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
func setupNameTextField() { nameTextField.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true nameTextField.topAnchor.constraint(equalTo: self.topAnchor).isActive = true nameTextField.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true nameTextFieldHeightAnchor = nameTextField.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4) nameTextFieldHeightAnchor?.isActive = true } func setupNameSeperatorView() { nameSeperatorView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true nameSeperatorView.topAnchor.constraint(equalTo: nameTextField.bottomAnchor).isActive = true nameSeperatorView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true nameSeperatorHeightAnchor = nameSeperatorView.heightAnchor.constraint(equalToConstant: 1) nameSeperatorHeightAnchor?.isActive = true } func setupSurnameTextField() { surnameTextField.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true surnameTextField.topAnchor.constraint(equalTo: nameSeperatorView.bottomAnchor).isActive = true surnameTextField.heightAnchor.constraint(equalTo: self.widthAnchor) surnameTextFieldHeightAnchor = surnameTextField.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4) surnameTextFieldHeightAnchor?.isActive = true } func setupSurnameSeperatorView() { surnameSeperatorView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true surnameSeperatorView.topAnchor.constraint(equalTo: surnameTextField.bottomAnchor).isActive = true surnameSeperatorView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true surnameSeperatorHeightAnchor = surnameSeperatorView.heightAnchor.constraint(equalToConstant: 1) surnameSeperatorHeightAnchor?.isActive = true } func setupEmailTextField() { emailTextField.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true emailTextField.topAnchor.constraint(equalTo: surnameSeperatorView.bottomAnchor).isActive = true emailTextField.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true emailTextFieldHeightAnchor = emailTextField.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4) emailTextFieldHeightAnchor?.isActive = true } func setupEmailSeperatorView() { emailSeperatorView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true emailSeperatorView.topAnchor.constraint(equalTo: emailTextField.bottomAnchor).isActive = true emailSeperatorView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true emailSeperatorView.heightAnchor.constraint(equalToConstant: 1).isActive = true } func setupPasswordTextField() { passwordTextField.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true passwordTextField.topAnchor.constraint(equalTo: emailSeperatorView.bottomAnchor).isActive = true passwordTextField.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true passwordTextFieldHeightAnchor = passwordTextField.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4) passwordTextFieldHeightAnchor?.isActive = true } |
Kurulum fonksiyonlarında bileşenlerin yerleşimini belirledik. Şimdi baştan kodlardan bahsedelim.
1 2 3 4 5 |
nameTextField.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true |
Burada ad bilgisini alacak olduğumuz “nameTextField”ın sol tarafını, oluşturduğumuz “View”ın sol tarafının 10 piksel içerisine alıyoruz.
Not: “isActive” özelliğini “true” olarak ayarlamayı kesinlikle unutmamalıyız. Aksi halde verdiğimiz sınırlamaların hiçbir anlamı kalmayacak, boşa yazılmış olacaklardır.
1 2 3 4 5 |
nameTextField.topAnchor.constraint(equalTo: self.topAnchor).isActive = true |
Burada ise “nameTextField”ın üst tarafı “View”ın üst tarafından başlayacak şekilde belirtildi.
1 2 3 4 5 |
nameTextField.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true |
“nameTextField”ın eni “View”ın enine eşitleniyor.
1 2 3 4 5 6 |
nameTextFieldHeightAnchor = nameTextField.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1/4) nameTextFieldHeightAnchor?.isActive = true |
Son olarak “nameTextField”ın yüksekliği belirleniyor. Burada yüksekliği bir değişkene atayarak yapıyoruz. Bunu yukarı gördüğüm şekilde de yapabilirdik fakat neden böyle yaptığımızı ileride konuşacağız.
Diğer tüm “textField”lar da benzer mantıkla kurulmuşlardır. Yalnızca bazılarının üst alanları diğerlerinin alt alanlarına gelecek şekilde düzenlenirler.
Son olarak sıra geldi tüm “textField”lar ve ayrıştırıcıların “View” üzerine eklenmesine. Bunun için de bir “createForm” adında fonksiyon yazıyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
func createForm() { self.addSubview(nameTextField) setupNameTextField() self.addSubview(nameSeperatorView) setupNameSeperatorView() self.addSubview(surnameTextField) setupSurnameTextField() self.addSubview(surnameSeperatorView) setupSurnameSeperatorView() self.addSubview(emailTextField) setupEmailTextField() self.addSubview(emailSeperatorView) setupEmailSeperatorView() self.addSubview(passwordTextField) setupPasswordTextField() } |
Her bir bileşeni önce alt ekran olarak ekleyip ardından kurulum fonksiyonunu çağırıyoruz. Burada da dikkat edilecek nokta bileşenlerin eklenme sırası ve eklenmeden kurulum fonksiyonlarının çağrılamayacağıdır.
Not: Yukarıdaki kodlarımızda arkaplan rengi ayarlarken 3 adet girdi alan bir fonksiyon kullandık bu sizde bulunmayacaktır. Bunu gerçekleştirmek için “UIColor” sınıfına bir eklenti yapıyoruz. Eklentimizde istediğimiz 3 girdiyi alan fonksiyonu aşağıdaki gibi yazabiliriz.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
extension UIColor { convenience init(red: CGFloat, green: CGFloat, blue: CGFloat) { self.init(red: red/255, green: green/255, blue: blue/255, alpha: 1) } } |
Böylece girdileri alacağımız “View” hazır hale gelmiştir. Şimdi “Controller” sınıfından çağıralım.
1 2 3 4 5 |
let inputContainerView: InputViewContainer = InputViewContainer() |
Öncelikle yukarıdaki gibi bir nesne yaratalım.
Ardından nasıl bir önceki sınıfımızda “textField”lar ve ayrıştırıcılar için kurulum fonksiyonları yazdıysak burada da tüm “View” için bunu yapacağız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
func setupInputContainerView() { view.addSubview(inputContainerView) inputContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true inputContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true inputContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true inputsContainerViewHeightAnchor = inputContainerView.heightAnchor.constraint(equalToConstant: 150) inputsContainerViewHeightAnchor?.isActive = true } |
Kod bloğumuzda ilk satırda girdi ekranımızı hazır bulunan ekrana alt görünüm olarak ekliyoruz.
Devam eden 2 ve 3. satırda ise ekranın tam ortasında yer almasını sağlıyoruz.
4. satırımızda ise “View”ımızın enini ekran üzerinde hazır bulunan “View”ın eninden 24 eksik şekilde ayarlıyoruz. Bu işlemin mantığına bakmak gerekirse, hem görüntüyü en olarak ortalamış olduğumuz hem de 24 eksik yazdığımızdan sağ ve sol taraftan 12’şer piksel keserek ortalayacaktır.
Son olarak kurulum fonksiyonumuzu “viewDidLoad” fonksiyonundan çağırıyoruz.
Hatırlatma: “viewDidLoad” fonksiyonu, o an kullanılan “controller”ın görünümü hafızaya yüklendiği anda çağırılır.
İşin belki de en karmaşık aşamasını böylece bitirdik. Buraya kadar ki kısmı detaylıca anlattıktan sonra devam eden bileşenlerden daha kısa bahsedeceğim.
SegmentedController Sınıfı Oluşturma
Tüm bileşen sınıfları Cocoa Touch Class ile hazırlandığını bildiğimiz için burada da bu işlemi yapıyoruz. Bu kez alt sınıfı “UISegmentedController” yapıyoruz.
Yine bir “init” fonksiyonu yazacağız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
override init(frame: CGRect) { super.init(frame: frame) self.tintColor = UIColor(red: 0, green: 132, blue: 180) self.translatesAutoresizingMaskIntoConstraints = false self.insertSegment(withTitle: "Giriş", at: 0, animated: true) //Segment ekliyoruz self.insertSegment(withTitle: "Kayıt Ol", at: 1, animated: true) self.selectedSegmentIndex = 1 //Segmented Controller'ın başlangıçta hangi değeri işaret edeceğini gösteriyoruz (Burada "Kayıt Ol" seçildi) } |
SegmentedController’ın kurulum fonksiyonunda diğerlerinden farklı olarak bir de segmentedController’ın değerini takip edecek ve değiştikçe yapılması istenen işlemi yapacak fonksiyonu işaret edecek özelliği ekleme kısmı vardır.
1 2 3 4 5 |
loginRegisterSegmentedControl.addTarget(self, action: #selector(handleLoginRegisterChanges), for: .valueChanged) |
Burada segmentedController’ına bir amaç, hedef ekliyoruz. Bu amaç segmentedController’ın değeri değiştiği zaman gerçekleşecektir (for: .valueChanged). Aksiyon olarak ta ismi verilen fonksiyonu aktifleştirecektir ( action: #selector(handleLoginRegisterChanges).
“handleLoginRegisterChanges” fonksiyonuna aşağıda değineceğim.
imageView Oluşturma
Profil fotoğrafını seçmesi için kayıt ol ekranında bulunacak olan “imageView” için de alt sınıf olarak “UIImageView” alan sınıfı oluşturuyoruz.
1 2 3 4 5 6 7 8 9 10 11 |
override init(frame: CGRect) { super.init(frame: frame) self.image = UIImage(named: "profile_icon") //Başlangıç fotoğrafı olarak projemize asset olarak eklediğimiz fotoğrafı seçiyoruz. self.translatesAutoresizingMaskIntoConstraints = false self.contentMode = .scaleAspectFit //İleride fotoğraf seçildiğinde boyutuna göre güzel bir görüntü olmasını sağlıyoruz } |
Button Oluşturma
Son olarak tüm bilgiler dolduğunda giriş veya kayıt olmayı aktif hale getirecek butonumuzu yaratıyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor(red: 0, green: 132, blue: 180) self.setTitle("Kayıt Ol", for: .normal) self.translatesAutoresizingMaskIntoConstraints = false self.setTitleColor(UIColor.white, for: .normal) self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16) self.layer.cornerRadius = 20 self.layer.masksToBounds = true } |
SegmentedController’ın Değerine Göre Ekranın Değişmesi
İlk verdiğim fotoğraflarda göreceğimiz üzere segmentedController’da “Kayıt Ol” seçili olduğunda profil fotoğrafını seçebiliyoruz ve form üzerinde de doldurmamız gereken 4 alan oluyor. Bunun aksine, “Giriş” seçili olduğunda doldurulması gereken 2 alan ve profil fotoğrafı alanı kayboluyor. Bunları nasıl sağlıyoruz aşağıda göreceğiz.
Öncelikle “inputContainerView” kısmında bahsettiğim kısıtlamarı değişken ile vermek için değişkenleri yaratıyoruz.
1 2 3 4 5 6 7 8 9 |
var inputsContainerViewHeightAnchor: NSLayoutConstraint? var nameTextFieldHeightAnchor: NSLayoutConstraint? var surnameTextFieldHeightAnchor: NSLayoutConstraint? var emailTextFieldHeightAnchor: NSLayoutConstraint? var passwordTextFieldHeightAnchor: NSLayoutConstraint? |
Kısıtlamaları global olarak tanımlamak iyi olacaktır çünkü genelde kullanıldıkları birden fazla sınıf olacaktır. Ben bunu “Constant” adında boş bir sınıf yaratıp, değişkenleri veya sabitleri buraya yazarak gerçekleştiriyorum.
Şimdi “segmentedController”da bahsetmiş olduğum “handleLoginRegisterChanged” fonksiyonunu yazacağız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
@objc func handleLoginRegisterChanges() { //kayıt ol-giriş yap butonu ismi let title = loginRegisterSegmentedControl.titleForSegment(at: loginRegisterSegmentedControl.selectedSegmentIndex) loginRegisterButton.setTitle(title, for: .normal) inputsContainerViewHeightAnchor?.constant = loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 75 : 150 nameTextFieldHeightAnchor?.isActive = false nameTextFieldHeightAnchor = inputContainerView.nameTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 0 : 1/4) nameTextFieldHeightAnchor?.isActive = true inputContainerView.nameTextField.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 inputContainerView.nameSeperatorView.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 surnameTextFieldHeightAnchor?.isActive = false surnameTextFieldHeightAnchor = inputContainerView.surnameTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 0 : 1/4) surnameTextFieldHeightAnchor?.isActive = true inputContainerView.surnameTextField.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 inputContainerView.surnameSeperatorView.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 emailTextFieldHeightAnchor?.isActive = false emailTextFieldHeightAnchor = inputContainerView.emailTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 1/2 : 1/4) emailTextFieldHeightAnchor?.isActive = true passwordTextFieldHeightAnchor?.isActive = false passwordTextFieldHeightAnchor = inputContainerView.passwordTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 1/2 : 1/4) passwordTextFieldHeightAnchor?.isActive = true profileImageView.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? true : false } |
Yazdığımız fonksiyonun içeriğine göz atalım.
1 2 3 4 5 6 |
let title = loginRegisterSegmentedControl.titleForSegment(at: loginRegisterSegmentedControl.selectedSegmentIndex) loginRegisterButton.setTitle(title, for: .normal) |
Burada butonumuzun adını “segmentedController”ın seçili segmentine göre ayarlıyoruz. Yani biz “Kayıt Ol”u seçersek butonumuzun adı “Kayıt Ol” olacaktır.
1 2 3 4 5 |
inputsContainerViewHeightAnchor?.constant = loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 75 : 150 |
Şimdi de değişken olarak tanımladığımız “inputContainerView”ın yüksekliğini yine “segmentedController”ın seçili segmentine göre ayarlıyoruz. “Giriş” tıklandığında ekranda yalnızca 2 adet doldurulması gereken “textField” olacağından “View”ın yüksekliğini azaltıyoruz.
1 2 3 4 5 6 7 8 |
nameTextFieldHeightAnchor?.isActive = false nameTextFieldHeightAnchor = inputContainerView.nameTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? 0 : 1/4) nameTextFieldHeightAnchor?.isActive = true inputContainerView.nameTextField.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 |
Burada öncelikle “textField”ın aktif halde bulunan yükseklik kısıtlamasını etkisiz hale getirdik. Şimdi de yüksekliğini “segmentedController”ın değerine göre 0 veya tüm “inputContainerView”ın 1/4 katına eşitliyoruz. Kısıtlamayı tekrar aktif hale getirdikten sonra eğer “segmentedController”da “Giriş” seçili ise kaybolmasını istiyoruz.
Diğer tüm “textField”lar için aynı işlemi gerçekleştiriyoruz.
1 2 3 4 5 |
profileImageView.isHidden = loginRegisterSegmentedControl.selectedSegmentIndex == 0 ? true : false |
Son olarak ta “profileImageView”ı eğer “segmentedController”da “Giriş” seçili ise kaybolmasını için gereken ayarı yapıyoruz.
Tüm bu işlemler bittikten sonra elimizde basit bir “Giriş-Kayıt” ekranı oluşacaktır.
Mutlu günler dilerim.
Yazılmış olan kodlara buradan ulaşabilirsiniz.