Kursda üçüncü dersin son kısmında hızlıca Navigation Controller’ı görmüştük fakat yazmaya fırsat bulamamıştık. İyi de oldu, çünkü tek bir yazıda uzun uzadıya bütün dersi anlatmaktansa konulara göre bölerek anlatmak daha iyi olur kanaatindeyim.
iPhone uygulamalarında en çok kullanılan view controller’lardan biri de Navigation Controller’dır. Navigation Controller’da hiyerarşik bir düzen vardır. Genelde Table View’larla beraber kullanılır. Kullanıcı ilk Table View’dan bir satıra tıkladığında o satırla ilgili yeni bir view çağrılır. Eğer bu da bir Table View ise burdaki bir satıra tıklandığında bir sonraki ilgili view çağrılır. Her bir alt kademedeyken bir üst kademeye geri dönmek için Uygulamanın üst kısmındaki bar’da geri dönüş butonları otomatik olarak çıkar (Tabi o ekran için bir title -başlık- yazmışsak).
Şimdi basit bir uygulama ile Navigation Controller’in detaylarına inelim. Yemekler adında küçük bir uygulama hazırlayalım, ilk ekranda “Etli Yemekler, Zeytinyağlılar ve Çorbalar” şeklinde yemek kategorileri listelensin. Etli Yemekler’e tıklandığında “Orman Kebabı, Hünkar Beğendi, İskender” sıralansın. Zeytinyağlılar’a tıklandığında “Taze Fasülye, İmam Bayıldı, Barbunya” sıralansın. Çorbalar’a tıklandığında “Ezo Gelin, Tarhana, Yayla, Şehriye” sıralansın. Aslında kursda bu örneği işlemedik ama nasılsa blog’da zamanımız daha bol olduğu için sindire sindire anlayalım diye bu tarz bir örnek kullanmak istedim.Uygulamayı oluştururken Navigation Based taslağını kullanabiliriz. Fakat sıfırdan yapmayı öğrenirsek bu yapıyı bir sonraki daha karışık uygulamanın içinde (örneğin bir tab bar application içinde) bir parça olarak kullanmayı da öğrenmiş oluruz.
İlk olarak Xcode’da Window Based taslağını seçerek Yemekler adlı projemizi oluşturalım (Resim1). Resources klasöründeki MainWindow.xib dosyasına çift tıklayarak Interface Builder (IB)’ı açalım ve Documents penceresini inceleyelim (Resim 2). Library’den Navigation Bar Controller nesnesini tutup Documents’e bırakalım. Navigation Bar Controller’ın içinde RootViewController adında bir View Controller olduğunu görüyorsunuz (Resim 3). Bu View Controller’a daha önce gördüğümüz bir Custom View Controler, yahut bir Table View Controller koyabiliriz. Amacımız bir liste görünümü oluşturmak olduğu için Library’den Table View Controller’ı tutarak Documents’deki Navigation Controller’ın altındaki View Controller üzerine bırakalım (Resim 4).
[nggallery id=6]
Gördüğünüz gibi Table View Controller’ı Documents’e ekleyince içinde Table View nesnesi de geldi. Bu noktada iki ayrı yol izleyebilirsiniz. Birincisi bu Table View’i doğrudan kullanabilirsiniz. Table View Controller’ın kodlarını oluşturacak subclass dosyalarını projeye eklerken .xib file seçeneğini seçmenize gerek kalmaz. İkincisi; bu Table View nesnesini Documents’den silebilirsiniz, ama o zaman Table View Controller’ın kodlarını oluşturacak subclass dosyalarını projeye eklerken .xib file seçeneğini de işaretlemelisiniz ki fiziksel bir Table View nesnemiz olsun. Eğer ikinci yolu seçecekseniz Inspector’da Table View Controller’ın class dosyasının yolunu belirtirken nib file dosyasının yolunu da belirtmeyi unutmayın.
Biz ilk yöntemden devam edelim; Table View nesnemiz Documents’de kalsın. Table View’a çift tıklayarak çalışma ekranını görelim ve title kısmını “Yemekler” olarak değiştirelim (Resim 5). Eğer bu aşamada Xcode’da projemizi çalıştırırsak beyaz bir ekrandan başka bir şey göremeyiz. Bunun nedeni henüz Navigation Bar Controller’ımızın içindeki view’ı (Table View) window’a (görünen beyaz ekran) dahil etmemiş olmamız. Bunu Xcode ile uygulama yüklenir yüklenmez yapmalıyız. Önce YemeklerAppDelegate.h dosyasında UINavigationController nesnemizi cntNavBar değişkeni ile ekleyelim (elbette başka bir değişken kullanabilirsiniz), property’sini yazarken IBOutlet ifadesini koymayı unutmayalım. IB’de kullandığımız nesneleri Xcode’da kullanabilmek için IBOutlet dememiz gerekiyor (Resim 6). YemeklerAppDelegate.h dosyasında tanımladığımız cntNavBar değişkenini @synthesize ifadesi ile YemeklerAppDelegate.m dosyasında belirtmemiz gerektiğini de hatırlatayım. Bu sayede cntNavBar değişkeninin property’lerine kolayca ulaşmayı sağlamış oluyoruz. Şimdi bu cntNavBar nesnesinin view’ını (yani Table View) ana Window’a subview olarak eklemek için .m dosyasında en başta yer alan “application” methodunu kullanacağız (Resim 7). Title’ında “Yemekler” yazan Table’ımızı görebilmek için tek bir adım kaldı, IB’ye geri dönüp Documents’deki Navigation Controller’ı inspector üzerinden cntNavBar değişkeni ile ilişkilendirmek. Bunun için Documents’den Navigation Controller seçiliyken Inspector’dan New Referencing Outlets satırını tutup Documents’deki Yemekler App Delegate nesnesinin üzerine bırakmak ve gelen listedeki tek eleman olan cntNavBar’ı işaretlemek (Resim 8). Şimdi dosyalarımızı kaydedip Xcode’dan uygulamamızı çalıştırdığımızda boş Table View’ımızı “Yemekler” başlığı ile görebiliriz.
[nggallery id=7]
Listemizi gördük ama tablomuz boş. Çünkü bu tabloyu dolduracak daha dogrusu bu Table View’i kullanacak Table View Controller kodlarını henüz yazmadık. Yazmaya başlayalım. Xcode’da Classes klasörüne sağ tıklayıp Add -> New File -> UIViewController Subclass’ı (UITableView Controller subclass seçeneği işaretli olmalı, eğer yukarıda bahsettiğimiz ikinci yolu seçmiş olsaydık “With XIB for user interface” seçeneğini de işaretlemek gerekecekti) seçelim. Dosya adına YemeklerViewController diyebiliriz. YemeklerViewController.h ve YemeklerViewController.m adlı iki dosyamız oluştu. YemeklerViewController classını IB’de Documents’deki Table View Controller’ın kod dosyaları olarak göstermek için Documents’de Navigation Controller altındaki Table View Controller (Yemekler) seçiliyken Inspector’un en son tabında Class Identity değerini combodan YemeklerViewController olarak değiştirelim (Resim 10).
Şimdi YemeklerViewController.h dosyamızı uygulama yüklenince yemek kategorilerini basacak şekilde dolduralım. Bunun için basit bir dizi kullanabiliriz. Şu yazıda bu konu hakkında geniş tafsilat olduğundan kısaca belirteyim: YemeklerViewController.h dosyasında NSArray tipinde arrKategoriler adında bir dizi değişkeni oluşturun, @property ifadesini IBOutlet koymadan ekleyin (çünkü bu bir dizi değişkeni, ekranda gözle görülen bir nesne değil). YemeklerViewController.m dosyasında viewDidLoad fonksiyonu (view yüklenince otomatik çalışan fonksiyon) içerisinde arrKategoriler listesini doldurun, dizinin sonuna “nill” koymayı unutmayın (Resim 11). Sonra Table View’in kendine mahsus 3 fonksiyonunu linkini verdiğim yazıdaki gibi her satıra dizinin bir elemanı gelecek şekilde uygun şekilde doldurun (Resim 12).
Şimdi uygulamayı çalıştırdığınızda yemek kategorilerinin listelendiğini görüyoruz (Resim 13). Tabi doğal olarak satırlara tıklandığında herhangi bir değişiklik olmuyor. Senaryomuz gereği Etli Yemekler satırına tıklandığında ilgili yemeklerin gelmesini istiyoruz. Bunun için kategorilerimiz adedince yeni Table View Controller’lar ve dolayısı ile yeni Table View’lar oluşturmalıyız. Bunun için Xcode’da Classes klasörüne sağ tıklayıp Add -> New File -> UIViewController Subclass’ı (bu kez UITable View Controller subclass ve With XIB for user interface seçeneklerinin ikisi de seçili olsun) tıklayıp dosya adı olarak EtliYemeklerViewController yazalım. EtliYemeklerViewController.h, EtliYemeklerViewController.m ve EtliYemeklerViewController.xib adında üç dosyamız oluştu. Proje dosyalarımızın düzenli durması açısından .xib uzantılı dosyayı Resources klasörü altına taşımayı unutmayalım. EtliYemeklerViewController.h dosyasında yukarıda yaptığımız gibi NSArray tipinde bir dizi değişkeni oluşturup bu tablo yüklendiğinde satırları dizinin elemanları ile dolacak şekilde oluşturalım (Resim14).
Bu haliyle uygulamayı çalıştırsak dahi satırlara tıklanınca herhangi bir şey olmadığını görürüz. Çünkü YemeklerViewController’a “ilk satıra tıklanınca EtliYemeklerViewController’ın view’ini ana window’a yükle” demedik. Bunun için YemeklerViewController.m dosyasına öncelikle EtliYemeklerViewController dosyasını import etmeli sonra da yine YemeklerViewController.m dosyasındaki Table View Controller’la ilgili dördüncü önemli fonksiyon olan “tableView didSelectRowAtIndexPath” fonksiyonundaki yorum ifadelerini silip uygun şekilde değiştirelim (Resim 15):
[nggallery id=8]
Şimdi uygulamayı çalıştırdığımızda hangi satıra tıklanırsa tıklansın EtliYemeklerViewController’ının TableView’ini yüklediğini görüyoruz. Bunu değiştirmek için öncelikle diğer kategoriler için de yukarıdaki adımları tekrarlayıp ZeytinyaglilarViewController ve CorbalarViewController adıyla UITableView subclass dosyalarını .xib dosyasıyla birlikte oluşturalım ve içlerine uygun diziler (arrZeytinyaglilar ve arrCorbalar) tanımlayıp viewDidLoad fonksiyonlarında dizileri doldurup ilgili TableViewController fonksiyonlarında dizilerin satırlara yerleşmesini sağlayalım (Resim 16, Resim 17).
YemeklerViewController.m dosyasında yeni oluşturduğumuz subclass’ları da import edelim. Yine bu dosyada bulunan ve daha önce herhangi bir satıra tıklandığında EtliYemeklerViewController’ının yüklenmesini sağlayan kodu bu kez ilk satıra tıklayınca EtliYemeklerViewController, ikinci satıra tıklanınca ZeytinyaglılarViewController ve üçüncü satıra tıklandığında CorbalarViewController yüklenecek şekilde değiştirelim (Resim 18).
Artık gönül rahatlığıyla uygulamamızı çalıştırabiliriz (Resim 19). Tabi ki uygulamanın daha iyi olabilmesi için bir kademe daha aşağı gidilip hepsinin tariflerinin olduğu ekranları da tasarlamak gerek. Ama bu yukarıdaki işlemlerden hiç de farklı değil. Sadece yeni alt classları (Subclass) oluştururken mesela Ezo Gelin Çorbası’nın tarifinin yazılı olacağı view’ın controller’ini oluştururken UITableView subclass seçmemek gerek. Normal bir custom view işimizi görür. CustomView’in .xib dosyasını açıp içine yemek tarifini yazmalıyız. Sonra EzoGelinCorbasiViewController’ı CorbalarViewController.m’ye import edip bu dosyadaki ilgili Table View Controller fonksiyonuna “birinci satıra tıklandığında EzoGelinCorbasiViewController’i yükle” demeliyiz.
Bu yazı amacından fazla uzun olduğu için artık bundan sonrasını yazmıyorum ama uygulamanın dosyasını buradan indirdiğinizde Ezo Gelin Çorbası’nın nasıl yapıldığını görebilirsiniz (Resim 20).
[nggallery id=9]
Alt kısımlara gidildikçe Title’ın değişmesi için ilgili viewDidLoad fonksiyonuna örneğin şu ifadeyi ekleyebilirsiniz;
self.title=@”Ezo Gelin Çorbası”;
yayınladığınız örnekler benim gibi yeni başlayan arkadaşlar için gerçekten çok iyi..inşallah devamı gelir.
Table View Controllerda listede her satırda resim göstermek istiyorum fakat aşağı yukarı kaydırdıkça resimler birbirine giriyor. Bunun için bir örnek yapabilirmisiniz
Hocamiz bu konuyu derste islerken de o sorun ortaya cikmisti ve nedenini anlatmislardi. Cozumunu de anlattilar ama cok net hatirlamiyorum. Hucrelere birbirine karismamasi icin birer index mi ne veriyorduk sanirim. Hucrelerin tag’leri ile alakali bir sey olabilir. Malesef cok net hatirlamiyorum. Surada resimli bir ornek var, belki yardimci olabilir: http://blog.webscale.co.in/?p=284
öncelikle yardımlarınız için çok teşekkürler,ben böyle madde madde örneğin 2 saat matematik çalış,altında 1saat pc oyna gibi maddeler yazıp yanlarına yapıldığında tik-okey işareti konulmasını istiyorum bir bilginiz varsa ve yardımcı olursanız çok sevinirim.
Merhaba,
Resim 8 de sizde görünen Yemek App Delegate nesnesi gözükmüyor bu nesneneyi nasıl ekleyebilirim ?
beyler bilen birisi yardımcı olursa sevinirim ben adım adım gidiyorum bu uygulamadaki gibi yemekler yazısının altıdaki maddeler gözükmüyor sadece yemekler yazısı gözüküyor nerde hata yapıyor olabilirim herşey aynı komutlar falan acaba tam olarak sıralı mı yapamıyorum
Uygulamanın Dosyasını İndirdim Ama Xcode ile açmayı denediğimde (There is no SDK with the name or path “iphoneos” ) Hatası veriyor . Ne Yapmalıyım ?
Dosyayı indirip makinemdeki Xcode’la açtım, herhangi bir problem çıkmadı (http://drag2.me/3frezh9p). Xcode’un güncel olduğuna emin olun ve buid seçeneklerinden çok eskiden kullanılan iPhone OS (şuanda iOS) diye birşeyin işaretli olmamasına dikkat edin.