iOS Block-code with Property

Yeni yıla girdik malum. Benim normalde de tüm yılım bilgisayar başında geçtiği için yeni yıla da bilgisayarım ile kod yazarak girdim 🙂 Pişman mıyım. Tabii amsterdam’da yılbaşı kutlamak ya da başka bir yerde çılgınca eğlenip yılbaşı kutlamak daha cazip geliyor. Ancak kendi koyduğum hedefler doğrultusunda çok çalışmam gerek. Şimdiden kendime 2015 yılı öğrenme takvimi gibi bir şey hazırladım 🙂

Neyse konuya gelelim. Block-code Objectvice-C’de en çok kullandığım özelliklerden birisi. Çok severim. Hem kullanırlığı kolay hem OO(Object Oriented) yapısına oldukça musait. Şimdi;

Interface dosyamızın hemen üstüne bir type-definition yani typedef oluşturuyoruz;

typedef void(^DoSomething)(void);

Daha sonra interface dosyamızda property olarak tanımlayabiliriz.

@property (nonatomic, copy) DoSomething somethingBlock;

Implementasyon dosyamızda “.m” istediğimiz işlemleri gerçekleştirebiliyoruz. Ben sadece NSLog ile bir şeyler yazdırdım. Tabii objemizin instantie edilmiş olması gerekiyor.


SomeClass *class = [[self alloc] init];

class.somethingBlock = ^{
        NSLog(@"Hello new year!!");
    };

Şimdi kullanmak istediğimiz sınıfımdızda dot syntax yaparak kullanbiliriz.


SomeClass *class = [[SomeClass alloc] init];
class.somethingBlock();

Advertisements

iOS TextView Prefix

Yaptığımız projelerin bazı noktalarında text girdilerine ön ek “prefix” koymak isteyebiliriz. Bu telefon kodu olabilir, “Sayın” gibi ifadeler de kullanabiliriz. Kullandığımız bu ön eklerin silinmemesi için “UITextField” sınıfının “UITextViewDelegate” delege methodlarından olan “textView:shouldChangeTextInRange:replacementText” methodunu kullanarak yapabiliriz.

Yapmamız gereken ilk olarak önceki metin ile sonraki metinleri birleştirmek. Daha sonra bu birleşimi bir NSString değişkeni içerisinde tutup daha sonra if-else koşulu ile eklediğimiz ön ek metin değerin uzunluğunu kontrol edip eğer birleştirilen metin belirtiğimiz ön ek metinin uzunluğundan küçük ise ön ekimizin silinmesini engelliyoruz. Bunu aşağıdaki kod ile yapabilirsiniz;

Prefix “Ön Ek” değerimiz

static NSString *const PREFIX_TEXT = @"Merhaba, ";

TextView’ımıza ekleceğimiz ön eki giriyoruz.

myTextView.text = PREFIX_TEXT;

Daha sonra delege metodumuzla kontrolleri sağlıyoruz.



- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    
    // Eski text değeriyle yenisini birleştiriyoruz...
    NSString *combinedText = [textView.text stringByReplacingCharactersInRange:range withString:text];
    
    // Eğer kullanıcı 4. karakterlerden sonraki karakterleri silmek istiyorsa bir prefix oluşturuyoruz
    // daha sonra text'in başına ön ek koyuyoruz.
    if(combinedText.length < 4) {
        textView.text = PREFIX_TEXT;
        return NO;
    }
    else if(![[textView.text substringToIndex:4] isEqualToString:[combinedText substringToIndex:4]]) {
        return NO;
    }
    
    return YES;
    
}

iOS Table Empty View

Listeleme gerektiren ya da ekleme – çıkarma yaptığımız Table View bölümlerinde eğer listelenecek herhangi bir içerik olmadığını göstermek istiyorsak iki yolu var. Birisi Alert View kullanmak ikincisi de table view’a direk mesaj yazmak. İkincisi her zaman terciğim. Ancak genelde table listesinin hücresine(cell) yazmayı tercih ediyordum. Bu da bir çok gereksiz koşul koymamı sağlıyordu. Bugün daha güzelini keşfettim. Table listesinin üzerine başka bir view eklemek ve dolu-boş koşuna göre göster-gizle yapmak. Kulağa mantıklı geliyor değil mi ? Yani “Talk is cheap show me your code.” diyenlerdenseniz aşağıya göz atabilirsiniz.
viewDidLoad:


- (void)viewDidLoad {
    [super viewDidLoad];

    // Global declared 'noMatchedView'
    noMatchedView = [[UIView alloc] initWithFrame:self.view.frame];
    noMatchedView.backgroundColor = [UIColor whiteColor];
    
    noMatchedLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
    noMatchedLabel.font = [UIFont boldSystemFontOfSize:18];
    noMatchedLabel.numberOfLines = 1;
    noMatchedLabel.shadowColor = [UIColor lightTextColor];
    noMatchedLabel.textColor = [UIColor darkGrayColor];
    noMatchedLabel.shadowOffset = CGSizeMake(0, 1);
    noMatchedLabel.backgroundColor = [UIColor clearColor];
    noMatchedLabel.text = @"Takas edeceğiniz ürününüz yok.";
    noMatchedLabel.textAlignment = NSTextAlignmentCenter;
    noMatchedView.hidden = YES;
    [noMatchedView addSubview:noMatchedLabel];
    [self.tableView insertSubview:noMatchedView belowSubview:self.tableView];
}

daha sonra tableView:numberOfRowsInSection delegate metodunda göster-gizle işlemini yapabiliriz.


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    if(self.items.count == 0) {
        self.tableView.separatorColor = [UIColor clearColor];
        noMatchedView.hidden = NO;
    } else {
        noMatchedView.hidden = YES;
    }
    return self.items.count;
}

Ayrıca aşağıdaki hazır ve gayet güzel olan TableView / CollectionView ile uyumlu bir kütüphane var.
https://github.com/dzenbot/DZNEmptyDataSet

iOS Call dynamic class

iOS projelerinde sıkça table view controller yapılarını kullanırız. Bu yapı geliştiriciye bir çok yeniliği getirdiği gibi aynı zaman da geliştirme sürecini de önemli ölçüde azaltığını düşünüyorum. Bu yazımda da bahsetmek istediğim şey dinamik olarak projemizin package’ında bununan herhangi bir sınıfı tableview’in cell’inin herhangi birine tıkladığında çağırılmasını işleyeceğiz. Örneğin kullanıcı 1. indexe sahip cell’e tıklarsa Class1.m sınıfını çağırmayı göstermeye çalışacağım.

TableViewController’ı oluşturduğunuzu ve tableView:didSelectRowAtIndexPath:indexPath metodunun içerisine aşağıdaki kodu yazalım;


NSString *viewControllerClassName = [NSString stringWithFormat:@"Class%@ViewController", @(indexPath.row + 1)];
Class viewControllerKlass = NSClassFromString(viewControllerClassName);
NSAssert(viewControllerKlass, @"Sınıf tanımsız olmamalı!");
NSAssert([viewControllerKlass isSubclassOfClass:[UIViewController class]], @"Tanımladığınız sınıf UIViewController sınıfına ait olmalı!");

UIViewController *demoViewController = [[viewControllerKlass alloc] initWithNibName:nil bundle:nil];

// belirtilen sınıf package da varsa navigationcontroller'a push et.
if (demoViewController) {
       [self.navigationController pushViewController:demoViewController animated:YES];
}

TableViewController’ımız da 4 adet cell olduğunu varsayarak sınıflarımız sırasıyla ;

Class1ViewController.m
Class2ViewController.m

şeklinde olmalıdır.

My iOS Development Arsenal

Bu yazımda iOS development yaparken geliştirme sürecimi kısaltan ya da güzelleştiren bir kaç eklentiden bahsedeceğim.

KSImageNamed
Programatik olarak oluşturuduğunuz UIImage sınıfına Asset dosyanızda bulunan .png ya da .jpg formatındaki resimleri önizlemenizi sağlıyor. Sadece [UIImage imageNamed:]; şeklinde çalışıyor.

https://github.com/ksuther/KSImageNamed-Xcode

Color Sense for Xcode
UIColor ile oluşturduğumuz renkleri hem önizlememizi hem de RBG şeklinde ayarlamamızı sağlıyor. Ayrıca rengi belirledikten sonra renge tıklayıp Color Picker bile açabiliyorsunuz. Oradan seçtiğiniz herhangi bir renk direk olarak RGB şekilde kodunu otamatik olarak kendisi yazıyor.

https://github.com/omz/ColorSense-for-Xcode

FLEX Inspector
Spark ve Reveal Inspector gibi ios uygulamanızın herhangi bir view’ını seçmenizi üzerinde herhangi bir property varsa görmenizi sağlıyor. FLEX ve DCIntrospect’in faydası diğer desktop inspectorlerdeki gibi Build Phareses’da fazladan işlem yapmanız gerekmiyor.

https://github.com/Flipboard/FLEX

DCIntrospect
Buda FLEX gibi bir inspector alternatik olsun diye paylaştım.

https://github.com/domesticcatsoftware/DCIntrospect

Custom Loader with UIActivityIndicatorView

Eğer loader işlemlerinizde üçüncü parti bir kütüphane kullanmak istemiyorsanız kendiniz bir UIViewController oluşturup custom bir loadar yapabilirsiniz. UIImageView’in animatedImages özelliğini kullanarak sekans sekans görüntüsü alınmış imajları pre-loading şekilde gösterebiliriz. Aşağıdaki bahsettiğim kod tam da bu işe yarıyor.

UIImageView *preloadingImageView = [[UIImageView alloc] init];
preloadingImageView.animationImages = @[@"image_sequence_01.png",@"image_sequence_02.png",@"image_sequence_03.png"];
[self.view addSubview:preloadingImageView];
[preloadingImageView startAnimating];

İsterseniz viewDidload:animated: methodunda bir de arkasına overlay view atarak daha güzel bir hale getirebilirsiniz. Ayrıca diğer sınıflarda da kullananmak isterseniz singleton hale getirebilirsiniz ya da label ekleyebilirsiniz.