2018年10月18日 星期四

提早拿到constraint後的frame

加入viewDidLoad可以拿到autolayout後的正確frame

加在animation中,可以在autolayout的情況下作用
[UIView animateWithDuration:0.5 animations:^{
            self.filterViewWidthConstraint.constant = 200;
            [self.view layoutIfNeeded];
        }];

用pdf取代png

在asset中放入pdf,設成all scale,可以用來取代svg當作向量圖。

如果是icon的話,還可以設成templete,可以用tintColor來改變icon的顏色。

超級實用的小技巧

2018年10月15日 星期一

Add touch began to pan gesture

!!!!!!一定要做#import "UIPanGestureRecognizerSubclass.h"
然後用category或是subclass去設定這個state,
才能用readwrite不然,原本的recognizer是readonly










@interface TouchableImageView:UIImageView
@property(strong, nonatomic) UIPanGestureRecognizer *panGR; // 這裡要改成自己的recognizer或是實作一個category
@end

@implementation TouchableImageView
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.panGR.state = UIGestureRecognizerStateBegan;
}
@end
//直接改狀態就能trigger gesture的began!!

2018年9月24日 星期一

用自己的dependency專案到cocoapods中

我送了一個pull request 到starscream,增加了支援http proxy的功能,
但遲遲沒有人審核,這時只好在專案中使用用自己的github上的版本。
問題是startcream只是Socket.IO-clinet這個專案的dependent project,
而Podfile不支援更來url來使用你自己project來作為其他專案dependent project。

所以我必須要在podfile中取消dependency再把二個專案都加入pods
建好xcworkspace檔案之後,再手動修改pod.xcodeproj來連Socket.IO-clinet使用starscream來build
  1. 去Socket.IO-clinet的project
  2. 去Build Phases
  3. 在Target Dependencies 中加入starscream
  4. 在Link Binary With Libraries 加入 starscream
  5. 最重要的是在Build Settings中把Framework Search Paths中把starscream的位置"$PODS_CONFIGURATION_BUILD_DIR/Starscream"加進去 (記得要在上面選到All才看得到這個設定)
P.S.
另一個方式是把starscream設為private pod,然後用podfile就可以取得。

2018年7月1日 星期日

predicateWithFormat在比對NSNumber的坑

環境: iOS SDK9
在你想比對NSNumber時,從JSON轉出來的數值出現了NSTaggedPointerString,你會比對不到,於是得到nil.
- (Visitor *)visitorByID:(NSNumber *)uid {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setEntity:[NSEntityDescription entityForName:@"Visitor" inManagedObjectContext:self.managedObjectContext]];
   
    if ([uid isKindOfClass:[NSNumber class]]) {
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"self.visitor_id == %@", uid]];
    } else {
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
        NSNumber *numUid = [numberFormatter numberFromString:(NSString *)uid];
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"self.visitor_id == %@", numUid]];
    }
       
        NSError * error = nil;
        NSArray * result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
       
        if (error!=nil) {
            SOLogError(@"%s[%d:%s]: %@", __FILE__, __LINE__, __FUNCTION__,error.localizedDescription);
        }
}

解法:
把NSTaggedPointerString再轉回NSNumber一次
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSNumber *numUid = [numberFormatter numberFromString:(NSString *)uid];

CoreData的performBlock和performBlockAndWait的差異

performBlock
會異步執行在context的thread之中(不會阻塞當前的thread)


performBlockAndWait


會同步執行在context的thread之中(會阻塞當前的thread,直到執行完block中的code再返回)


NSManagedObjectContext save()

https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506866-save
https://developer.apple.com/documentation/coredata/nsmanagedobjectcontext/1506954-haschanges