SpeechRecognizer ile Ses Kaydetmek

Merhaba bu yazımda SpeechRecognition modülünü kullanarak iPhone’un mikrofonundan faydalanmayı anlatacağım.

Örnek proje üzerinden bir uygulama yapacağız ve gerekli yerlerde açıklama yapacağım.

 

Örnek Proje

Basit bir ses kaydetme uygulaması yapacağız. Swift 4.2 ile uyumlu olacak.

SingleView bir Swift projesi yarattıktan sonra info.plist dosyasını açıp aşağıdaki keyleri ve açıklamaları ekleyelim.

 

Kullanıcı uygulamayı açtığında önce bu izinleri vermesi gerekecek.

 

ile Speech modülünü import edelim.

 

Speech web tabanlı çalışan bir modüldür. Projenin düzgün bir biçimde çalışması için internet bağlantınızın olması gerekiyor.

 

İsterseniz SpeechRecognition özelliğini ayrı bir class içinde gerçekleştirelim.

Daha sonra işimize yarayan tüm değişiklikleri bir delege fonksiyonuna atarız ve diğer sınıf içinde implement ederiz.

Böylece asıl class içinde kod kalabalığı yapmamış oluruz.

 

Eğer delegation hakkında merak ettikleriniz varsa Delege & Protokol Kullanımı yazıma bakmanızı tavsiye ederim.

 

Şimdi protokolü, delege metodunu, sınıfı ve değişkenleri tanımlayalım.

 

Yukarıda yazdıklarımı biraz açıklayayım:

 

SpeechRecognitionModalDelegate protokolü içinde didPrepareSpeech isminde bir delege metodu oluşturduk.

Oluşturduğumuz bu metod sayesinde şunları yapacağız:

  • Yazıya döktüğümüz konuşmayı canlı olarak alacağız,
  • Konuşmayı başlatmak için kullandığımız butonun aktif/pasif durum bilgisini anlık olarak elde edeceğiz.

 

SpeechRecognition ile ilgili tüm işlemleri bundan oluşturduğumuz bir obje üzerinden gerçekleştireceğiz.

SpeechRecognition API sine istekleri web servisi üzerinden yapıyoruz. Bu nedenle web servisine istek atacak request ve bunları gerçekleştirecek task objesine ihtiyacımız var.

Tüm ses sinyallerini AVAudioEngine yönetir. Bu nedenle bundan oluşturduğumuz bir objeye ihtiyacımız var.

lang değişkeni kullanılan cihazın başlatma dilini alıyor. Eğer iPhone’u türkçe kullanıyorsanız lang değeri “tr” olacaktır.

timer değişkenini ise sessizlik anında audioengine i durdurmak için kullanacağız.

 

Bu değişkenlerin hepsi private çünkü dışarıdan müdahale edilmesini istemiyoruz. Erişilmesini istediklerimizi zaten delege edeceğiz.

 

Kullanıcı İzinleri

 

Şimdi bir customInit() metodu yazalım. Bu metodu sınıfın kendisinden bir obje oluşturduktan sonra viewDidLoad() içinde çağıracağız.

 

SpeechRecognizer için gerekli tanımlamaları yaptık ve kullanıcıdan mikrofonu kullanabilmek için izin istedik.

Bunun sonucunda mikrofonun isEnabled statüsünü belirledik ve bunu delege metoduna gönderdik.

 

Buton Aksiyonu

 

Daha sonra yapmamız gereken mikrofon butonuna bastığımız zaman neler yapılacağını ayarlamak. Bunun için ise micButtonPressed adında bir metod hazırlayalım ve aşağıdaki kodları yazalım. Bu fonksiyonu daha sonra mikrofon butonunun aksiyonu içinde çağıracağız.

 

 

 

Keşke startRecording() diyip bütün işimiz bitse değil mi 😀

Ama yok öyle yağma, bi startRecording() fonksiyonu yapalım bakalım:

 

Bu metod ile ses kayıt işlemi sırasında yapılması gerekenleri belirttik. Çok kabaca şunu yapıyoruz:

Canlı olarak konuştuğumuz her kelime result bloğunun içine düşüyor ve biz onun string halini delege metoduna gönderiyoruz.

Ayrıca, eğer error un değeri nil değilse restartSpeechTimer diye bir fonksiyon çağırıyoruz. Yazacağımız bu fonksiyon timer fonksiyonunu çağırarak callback mekanizması içinde kendisini yeniden çağıracak.

 

Yazalım o zaman…

 

Bu fonksiyonumuz eğer 1.5 saniye içinde ses gelmezse mikrofon dinleme özelliğini kapatıyor ve yeniden kullanılmak üzere hazırlıklarını yapıyor.

Ayrıca delege metodunu butonun durumu hakkında bilgilendiriyorki diğer sınıfın bu değişiklikten haberi olsun 🙂

 

Son olarak SpeechRecognizer modülünün availability ile alakalı olan delege metodunu çağırmamız gerek.

 

 

Son Dokunuşlar…

 

 

 

SpeechRecognitionModal sınıfında yapmamız gerekenler bunlardı.

Artık tek yapmamız gereken IBOutlet, IBAction bağlantılarını yaptığımız sınıfı açmak ve delege metodunu gerekli yerlerde implement etmek.

Bunun için şekildeki gibi bir sayfa tasarlayalım ve tasarımın bağlı olduğu ViewController sınıfı içinde label ve buton için IBOutlet bağlantısı yapalım.

Buton için ayrıca IBAction bağlantısı yapmayı unutmayalım.

Bunlar için verdiğim isimler sırasıyla; titleLabel, micButton, micButtonPressed

 

 

 

Son olarak yapmamız gereken SpeechRecognitionModalDelegate protokolünü sınıfın içinde çağırmak ve gerekli yerlerde kullanmak.

Tüm bunları yaptığımızda kodun son hali aşağıdaki gibi olacaktır:

 

Her ne kadar SpeechRecognitionModal sınıfında biraz uğraşmış olsak da ViewController sınıfımız yeterince temiz oldu.

 

Şimdi projeyi çalıştırabiliriz 🔥

 

 

 

Projenin kaynak koduna buradan erişebilirsiniz.

Bu yazı ile ilgili görüş ve önerilerinizi yorum bölümünden iletebilirsiniz. Ayrıca e-mail adresimden bana her daim ulaşabilirsiniz.

İyi günler.

Objective C İçinde Swift Kullanmak

Merhaba, bu yazımda Objective C projesi içerisinde Swift kodu yazmayı anlatacağım.

 

Giriş

Bildiğiniz üzere Objective C 30 küsür yaşında olmasına rağmen henüz ölmemiş bir dil. Stabil çalışıyor; bir çok kaynak var, binlerce geliştirici tarafından benimsenmiş ve kolay kolay Swift’e taşınamayacak kadar büyük Objective C ile yazılmış birçok yazılım ürünü var.

 

Kaynak: Cheesecake Labs

 

Öte yandan Swift dünyanın en popüler dilleri arasına girdi; arkasında muhteşem bir topluluk duruyor, syntax i kolay, uygulama güvenli geliştirilsin, patlamasın diye birçok kontrol mekanizması mevcut ve ileriki yıllarda tamamen Objective C nin yerini alacak.

 

Hal böyle olunca şu an için ikisinden de kopamıyoruz ve iki dili de aynı projede kullanma ihtiyacı hissediyoruz.

Şimdi isterseniz Objective C içinde Swift Kullanmak nasıl oluyor, öğrenelim.

 

Örnek Proje

SingleView bir Objective C projesi yaratalım.

 

 

Bunun eski bir Objective C projesi olduğunu düşünürsek ismine MyOldProject diyebiliriz sanırım 🙂

 

Projenin içine bir .swift dosyası ekleyelim Create Bridging Header diyelim. Class adına MySwiftClass adını verdim.

 

 

Bridging header ı oluştursun fakat içini boş bırakacağız.

Swift sınıfının içine girelim ve aşağıdaki gibi bir metod yazalım:

 

 

Farkettiyseniz bu sınıfta orijinal bir Swift projesinden farklı olarak kullandığımız @objc ön eki var.

ObjectiveC projesinin Swift sınıfını tanıyabilmesi için bu ön eki koymamız gerekiyor.

Keza aynı şekilde swift metodlarının tanınabilmesi için de metodların önüne @objc ekini koyuyoruz.

 

Şimdi proje sayfasına gelelim, target üzerine gelelim ve Build Settings başlığı altında “Always Embed Swift Standard Libraries” değerini YES ile değiştirelim.

 

Bu ayar Objective C İçinde Swift Kullanmak için önemli bir adımdı. Böylelikle Objective C projesinde swift kodu kullanmamıza izin vermiş olduk.

 

Bildiğiniz gibi Objective C projesi üzerinde çalışırken dahil etmek istediğimiz sınıfın header dosyasını çalıştığımız sınıfın içinde import ederizki onu tanısın.

Fakat Swift yazarken bir şey import etmiyorduk çünkü zaten bütün sınıflar birbirini tanıyordu.

Şimdi biz ne yapacağızda Swift ile yazdığımız sınıfın Objective C ile yazılmış sınıf tarafından tanınmasını sağlayacağız?

 

Xcode bu problemi çözmek için yalancıktan bir header dosyası oluşturmuş. Aslında fiziksel olarak böyle bir dosya bulunmuyor fakat build sırasında oluşturuyor. Eğer bu header dosyasının adını bilirsek ve Objective C sınıfının içinde bu header ı import edersek sorun çözülmüş olacak.

 

Header ismini öğrenmek için yine target seçili iken arama bölümünde “Objective-C Generated Interface Header Name” ismini aratalım.

 

Burada import etmemiz gereken header dosyasının ismini görüyoruz. Bir değişiklik yapmayacağız, sadece bu ismi kullanacağız.

Farkettiyseniz format şu şekilde “ProjeAdı-Swift.h”

Yani proje ismi verdikten sonra -Swift.h ekliyor. Her oluşturduğunuz Objective C projesi için swift header ismine bakmanıza gerek yok; söylediğim format aklınızda kalsın yeterli 🙂

 

Şimdi ViewController.m sınıfına dönelim ve swift header ını import edelim.

 

Import ederken alışık olduğumuz gibi auto-complete yapmayacak o yüzden endişelenmeyelim.

Ayrıca auto-complete denerken bridging-header diye bir şey koymaya çalışacak, bunu yapmayın.

 

Son olarak swift sınıfından bir obje yaratalım ve içindeki metodu çağıralım.

 

Sonuç

 

Bütün işlem bu kadardı. Şimdi projeyi derleyip başlattığımızda Swift kodunun Objective C projesinde başarıyla çalıştığını göreceğiz.

 

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

 

Projenin kaynak koduna buradan erişebilirsiniz.

 

İyi kodlamalar 💻

 

TableviewCell Aksiyonları

Merhaba, bu yazımda tablo hücresini sola kaydırınca çıkan aksiyonları ayarlayacağız.

Tableview çok büyük ve önemli bir konu. Tableview ile ilgili ne anlatmaya kalksam hepsini ayrı derslere ayırmam gerekiyor 🙂

Hücreyi sola kaydırınca çıkan aksiyonlar da bunlar da biri.

İngilizce swipe-to-edit, swipe-to-delete gibi anahtar kelimelerle arayınca çıkıyor fakat türkçe ne yazılır bilemedim 🙂

Neyse, başlayalım.

 

Örnek Uygulama

 

Bu yazıyı takip edebilmeniz için Tableview konusuna giriş seviyesinde de olsa hakim olmanız gerekiyor.

Eğer biraz eksiğiniz olduğunu düşünüyorsanız Tableview Kullanımı ve Custom TableviewCell Kullanımı derslerine bakmanızı tavsiye ederim.

 

Şimdi, zaten çalışan ve tablo verilerini listeleyen bir Tableview yapınızın olduğunu farz edelim.

Bu Tableview yapısına bir de bu bahsettiğim sola çekince çıkan aksiyonlar özelliğini eklemek için şu adımları takip edelim:

 

 

Tableview delegate metodlarını yazdığımız kısma biraz boşluk bırakıp bu metodu ekledik.

Burada UISwipeActionsConfiguration return ediyoruz ve içinde deleteAction isminde bir fonksiyon gönderiyoruz. Birazdan bu fonksiyonu oluşturacağız.

Dikkat ederseniz UISwipeActionsConfiguration bir Array. Yani hücre içine sadece bir aksiyon tanımlamamız gerekmiyor. Birden fazla aksiyonu yan yana koyabiliriz.

Önce ilkini halledelim sonra ikinciye geliriz, kafalar karışmasın 🙂

 

Biz şimdi deleteAction metodu yazalım.

Parametre olarak IndexPath değişken tipi tanımlıyoruz çünkü silme işlemini yaparken hangi hücre üzerinde işlem yaptığımızı bilmemiz gerek. Bu da ancak IndexPath bilgisini elde ederek mümkün.

 

 

 

Eğer players adında bir array kullanarak mTableView ismindeki tabloyu doldurduğumuzu farz edersek önce array in içinden bu elementi silmemiz; daha sonra ise Tableview den bu veriye karşılık gelen hücrenin silinmesi lazım.

Aksiyonun cavcavlı gözükmesini sağladığımız yer ise .image ve .backgroundColor property leri 🙂

İnternetten bulduğunuz bir çöp kutusu ikonunu Asset klasörüne sürükleyin ve delete ismini verin.

Arkaplan rengini ise kırmızı yapmayı tercih edelim.

 

Not:

Bu değişiklikler kalıcı değildir. Kullanım amacınıza göre gerçek hayatta NSUserDefaults veya web servisisindeki bir array elementini oradan silmeniz gerekiyor.

 

Bir de şu metodu yazalım:

 

TableView in bu delegate metodu ise hücrenin editlenebilir/editlenemez ayarını yapmamızı sağlıyor.

Eğer o hücrenin belirli şartlar altında editlenebilir veya editlenemez olmasını ayarlamak istiyorsanız bunu bir koşula bağlamanızı tavsiye ederim.

Örneğin şekildeki gibi Global sınıfı içindeki isAdmin değerini kontrol edebiliriz.

Eğer koşula gerek yok derseniz sadece return true demeniz kafi olacaktır.

 

Şimdi şunu yaptık:

 

 

Bir aksiyon daha…

 

Hadi şimdi bir aksiyon daha ekleyelim! Bu da edit aksiyonu olsun.

deleteAction u kopyalayalım ve birkaç yerini değiştirelim.

 

Bu metodu sadece bir template olsun diye ekledim. İsteğinize göre değiştirin.

Eğer edit aksiyonu almak istiyorsak muhtemelen başka bir sahneye geçiş yapmamız gerekecek ve performSegue kullanacağız. Bu kısmı yorum satırına aldım, uncomment yapmak serbest 🙂

 

Son olarak ilk yazdığımız trailing swipe action delegate metoduna edit aksiyonunu ekleyelim.

 

Burada şuna dikkat edelim: Array e koyduğumuz her element sola eklenerek devam eder.

Yani bu örnekte edit aksiyonu solda, delete aksiyonu ise sağda gözükecek.

 

 

Sonuç

 

Kabataslak olarak hücre aksiyonlarını anlatmaya çalıştım, geliştirmek ise size kalsın 🙂

Umarım faydalı olmuştur.

 

İyi kodlamalar 💻

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 💻

 

 

 

IBAN Numarası Formatlamak

Merhabalar, biraz aradan sonra IBAN Numarası Formatlamak dersi ile tekrar beraberiz 🙂

 

Giriş

iOS uygulama geliştirirken IBAN numarasıyla işlem yapmak istediğiniz oldu mu?

Birbirine bitişik uzun karakterler her zaman okuması zor olmuştur. Özellikle konu IBAN olunca yanlış numara yazma endişesi çoğu zaman stres yaratan bir durum.

Bu yüzden IBAN Numarası Formatlamak dersini hazırladım ve herhangi bir üçünü parti kütüphane vs kullanmaya gerek kalmadan bu işi çözeceğiz.

Her zamanki gibi örnek uygulama üzerinden gideceğiz ve ders sonunda projenin kaynak kodunu paylaşacağım.

 

Örnek Uygulama

SingleView bir Swift projesi yaratalım ekranın ortasına bir TextField yerleştirip Auto-Layout ile sabitleyelim.

 

Assistant Editor’u açalım, IBOutlet bağlantısını yapalım, TextField delegesini yazalım ve klavyeyi dokunmaya duyarlı hale getirelim.

 

Bildiğimiz gibi IBAN numarası Türkiye’de TR kodu ile başlar ve gerisi genelde sayısal rakamlar ile devam eder.

Tabii ki istisnai durumlar da olabilir. Örneğin IBAN alfabetik karakter içerebilir veya karakter sayısı farklı olabilir. (Uyardığı için Atakan Bey’e teşekkürler)

Eğer alfabetik karakter de girilsin istiyorsanız klavye türünü alfa-numerik seçebilirsiniz.

Onun haricinde karakter sayısını fix kabul edeceğiz.

 

O zaman şöyle bir şey yapalım:

Ekran klavyesini sadece numerik data girecek şekilde ayarlayalım ama IBAN alanına dokunduğumuzda TR ön eki otomatik olarak yazılmış olsun.

 

Bunun için,

Ekran klavyesini ayarlayalım.

 

Daha sonra TextField dan bir Aksiyon yaratalım ama Event türünü “Editing Did Begin” olarak ayarlayalım.

 

Dolayısıyla text alanına ne zaman dokunsak bu aksiyonu tetiklemiş olacağız.

Buraya diyeceğizki, eğer içinde “TR” ibaresi yoksa “TR” yaz, eğer varsa bir şey yapma.

 

Şimdi editleme esnasında çağrılacak fonksiyonumuzu yazalım.

 

Son olarak text alanında yaptığımız tüm değişikleri takip eden shouldChangeCharactersIn metodunu yazalım ve format fonksiyonunu bunun içinde çağıralım.

 

Bu delege metodunda seçtiğimiz TextField, ibanNoTextField mi diye kontrol ediyoruz, eğer oysa gerekli işlemleri yapıyoruz. Bu kontrolü mutlaka yapın yoksa değişikler tüm TextField larda meydana gelir, bu da istemediğimiz bir şey 🙂

 

Tüm işlem bu kadardı.

 

Projeyi çalıştıralım. 🔥

 

 

Not

  • İsterseniz ayraç olarak boşluk yerine çizgi (-) vs kullanabilirsiniz.
  • Türkiye’de bazı gösterimler TRXX XXXX şeklinde devam ederken bazen de TRXX XXXX kullanımı oluyor. Ben uygulamalarımda ikinci yöntemi tercih ediyorum.

 

kodu isteğinize göre değiştirin 🙂

 

Projenin kaynak koduna buradan erişebilirsiniz.

 

Birdahaki derste görüşmek üzere.

 

İyi kodlamalar 💻

 

Custom TableViewCell Kullanımı

Merhaba, bu yazıda custom tableview cell konusunu işleyeceğiz.

Custom TableViewCell Nedir?

Bildiğiniz gibi TableView yapısı iOS uygulamalarında sıkça kullandığımız bir yapı. TableView ile yazı ve resimleri tablo halinde kolayca listeleyebiliriz fakat bu tablo hücreleri çok kısıtlıdır. Bir TableView hücresinde şunları gösterebiliriz:

  • Sadece başlık
  • Başlık ve Altbaşlık
  • Bunlarla beraber resim

Peki bunlar işimizi her zaman görüyor mu? Görse bile görünüşünü ve pozisyonlarını istediğimiz gibi ayarlamamıza yetiyor mu?

Tabiki hayır.

İşte bu yüzden TableView hücrelerini özelleştirmek istiyoruz.

İsteğe göre özelleştirilmiş her hücreye Custom TableViewCell adı veriliyor.

 

Custom TableViewCell Ne İşe Yarar?

Custom TableViewCell kısaca Apple’ın bize standard olarak sunmuş olduğu TableView yapısını değiştirerek isteğe göre yeniden dizayn edebilmemizi sağlar.

Hücre elemanlarını ve pozisyonlarını, hücre büyüklüğünü, görüntüsünü ve şekli şemalini komple biz tasarladığımız için inanılmaz bir esneklik sağlar.

Yapabilceklerimiz ise hayal gücümüzle sınırlı 😎

 

Yani şimdi şu da bir TableView hücresi:

 

Bu da bir TableView hücresi…

 

Şimdi hangisi daha güzel allaasen? Biz de TableView hücrelerini böyle şeküllü şukullü yapacağız 🙂

 

Custom TableViewCell nedir ve ne işe yarar öğrendik. Şimdi sıra geldi örnek uygulamasına…

 

Eğer TableView hakkında eksik olduğunuzu hissettiğiniz noktalar varsa TableView Kullanımı dersine bakmanızı tavsiye ederim.

 

Hadi başlayalım 🔨

 

Örnek Uygulama

SingleView bir uygulama başlatalım, MainStoryBoard’a bir adet TableView sürükleyelim, ekranın hepsini kaplasın. Bunun için Auto-Layout kullanabilirsiniz.

Ayrıca 1 adet prototip yaratalım ve identifier olarak “Cell” ismini verelim.

Delegate, Datasource, IBOutlet bağlantısı vs gibi işleri önceden yaptığınızı varsayıyorum çünkü biz bu derste özelleştirilmiş tablo hücresi öğreniyoruz, TableView zaten biliyoruz değil mi 🙄

Custom TableView Cell oluştururken atacağımız ilk adım hücrenin uzunluğunu ayarlamak olsun.

Bunu iki farklı yerden ayarlamamız gerekiyor.

Birincisi TableView üstünden olacak, diğeri ise hücre üzerinden.

 

 

TableView objesi seçiliyken Size Inspector’a gelelim ve Row Height olarak 110 verelim.

 

Bir de TableView hücresi seçiliyken yine Size Inspector’dan Row Height olarak 110 birim belirtelim.

 

 

Tablo hücresini seçmekte zorlanırsanız sol taraftaki Document Outline yapısını kullanabilirsiniz.

 

Şimdi geldik hücre tasarımına…

 

Hücre seçiliyken eklemek istediğimiz objeleri buraya sürükleyip Auto-Layout ile constraint vereceğiz.

Hücrenin içine bir adet ImageView sürükleyelim, kenarlarını tüm köşelere doğru uzatalım ve Content Modunu Aspect Fill seçelim. Ayrıca ImageView in Alpha değerini 0.3 yaparak saydamlaştıralım.

 

Daha sonra hücreye label sürükleyelim ve 25 Punto Bold bir font belirleyelim. Daha sonra bunu ekranın ortasına sabitleyelim.

 

Bir tane daha label eklersek tasarım işi bitiyor. Bu label ı ise ekranın sağına ve ortasına sabitleyelim, puntosu daha küçük olsun.

 

Tasarım işi bitti. Peki bunların IBOutlet bağlantılarını nerde yapacağız?

UITableViewCell class ı oluşturup onun içinde yapacağız. ViewController class ında bağlantı oluşturmayın.

 

Şimdi projede yeni bir CocoaTouch dosyası yaratalım. İsmi myTableCell olsun. Extend ettiği class ise UITableViewCell olsun.

 

Hücrenin içindeki objelerin bağlantılarını bu hücre sınıfı içinde yapacağız ama önce tablo hücresinin bu sınıfı kullanacağını belirtmemiz gerekiyor. Bu nedenle hücre seçiliyken Custom Class olarak yarattığımız myCell sınıfını seçmemiz lazım.

 

Şimdi bağlantıları yapabiliriz.

Assistant Editor myCell sınıfı ile açıkken IBOutlet bağlantılarını yapalım.

 

Hücre artık hizmete hazır ve nazır hale geldi 🙂

 

Şimdi tabloda göstermek üzere biraz veri hazırlayalım. İnternetten 3 adet kebap resmi bulalım, ben aşağıdakileri kullanacağım 😋

 

 

 

 

 

 

Bunları Asset klasörünün altına attıysak şekildeki gibi bir Tuple oluşturalım…

 

Bu da tamam.

Geriye kaldı TableView delege metodları…

 

Hatırlarsanız TableView in delege metodlarını yazarken cellForRowAt fonksiyonunda bir hücre yaratıyor ve sonra bu hücreyi return ediyorduk.

Ama bu yarattığımız hücreyi default tableview hücresine cast ederek kullanıyorduk.

Şimdi yapacağımız şey ise default hücreye cast etmek yerine yarattığımız myCell sınıfına cast etmek 🙂

 

Neler yaptık?

  • “Cell” ismi verdiğimiz hücreden bir instance yarattık ve bunu myCell sınıfına cast ettik.
  • myCell içinde tanımladığımız hücre property lerini sırasıyla tuple verilerine eşitledik.

 

Yemeğin ücretine türk lirası sembolünü sonradan ekledik çünkü normal şartlarda fiyat bilgisi veritabanından gelir ve Integer ve Double tipinde numerik bir veri döndürür. Biz artık bunu nasıl display etmek istiyorsak sağına soluna başına farklı semboller koyabiliriz. Bu daha doğru bir çözümdür.

Üşenmeyelim, böyle yapalım 🙂

 

Sonuç

Yukarıdaki adımları eksiksiz tamamladıysak projeyi çalıştırabiliriz 🔥

 

 

Bütün işlem bu kadardı.

Custom TableViewCell ile ilgili anlatacaklarım basit haliyle bu kadar. İlk defa öğrendiğiniz bir şey ise bu dersin üzerine yeni birşeyler ekleyip denemenizi tavsiye ederim. Hatta buraya da paylaşırsanız on numara olur 🙂

 

Projenin kaynak koduna buradan erişebilirsiniz.

 

Sizce custom TableViewCell kullanılması gerekli bir yapı mı? Siz uygulamanızda kullanmak ister misiniz?

 

İ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 💻

 

Balon Şeklinde Etiket Oluşturmak

Swift ile balon şeklinde etiket nasıl oluşturulur merak ediyorsanız sizi içeri alalım 🙂

Devamını Oku

Beni Hatırla Özelliği Yapmak

 

iOS uygulamanızın login ekranında beni hatırla özelliği yapmak ister misiniz?

Devamını Oku