iOS |知识点整理(2)

454 阅读22分钟

延续上一篇 iOS |知识点整理(1)

7.拖动停止,用来记录拖动停止时的相关记录.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0){
    _svcontentOffsetY = _svQues.contentOffset.y;
}

6.strUrl1 = [strUrl1 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

5.可以在navigationController的delegate中得到navigationController

using the UINavigationControllerDelegate you can use thenavigationController:willShowViewController:animated: method to access the navigationBar

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
 
}

4.mac四指前推-任务栏 mac五指散开-桌面 五指收拢-lunch 二指-滚动

  1. view.userInteractionEnabled=NO; 让一个view禁止响应

2.totalBytesExpectedToRead in setDownloadProgressBlock remains -1 until download is done

Download progress may return -1 if the server does not set the Content-Length HTTP header in the response. In this case, it is recommended that you use an indeterminate progress indicator instead.

1.NSURLSession 是 iOS 7 新引入的用于替代 NSURLConnection 的类。NSURLConnection 并没有被弃用,今后一段时间应该也不会,但是 NSURLSession 是 Foundation 中网络的未来,并且是一个美好的未来,因为它改进了之前的很多缺点

3.popToViewController的api的用法. 1.UIWebView中的缩放控制

2.UIScrollView对键盘出现时机的支持

1.[[UIScreen mainScreen] applicationFrame] 与[[UIScreen mainScreen] bounds]的区别
   1.CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
    UIScrollView *scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];
对应显示:

   2. CGRect fullScreenRect=[[UIScreen mainScreen] bounds];
    UIScrollView *scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];

对应显示:

2.关于子视图的index,最后添加的子视图的index为0 push 后进先出

 //红色UIView
    UIView *redView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];  //子视图的index是3
     //黄色UIView
    UIView *yellowView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    yellowView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:yellowView]; // //子视图的index是2
   
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button setTitle:@"改变" forState:UIControlStateNormal];
    button.frame = CGRectMake(10, 10, 300, 40);
    [self.view addSubview:button];  //子视图的index是1
   
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button1 setTitle:@"改变1" forState:UIControlStateNormal];
    button1.frame = CGRectMake(10, 60, 300, 40);
    [self.view addSubview:button1];  //子视图的index是0
//如果要交换红色view与黄色view的显示层次
    [self.view exchangeSubviewAtIndex:2 withSubviewAtIndex:3]; 

3.图片的放大缩小:

要实现 UIScrollViewDelegate 协议

- (void)viewDidLoad{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
    UIImage *image = [UIImage imageNamed:@"big.jpg"];
    self.iv = [[UIImageView alloc] initWithImage:image];
    self.iv.frame = CGRectMake(0, 0, image.size.width, image.size.height) ;
   
    CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
    UIScrollView *scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];
    [scrollView addSubview:self.iv];
    scrollView.contentSize=CGSizeMake(image.size.width ,image.size.height);
    scrollView.delegate=self;
    scrollView.minimumZoomScale = 0.2;
    scrollView.maximumZoomScale = 2.0;
    [self.view addSubview:scrollView];
}

-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    CGPoint upperLeftOfVisible = scrollView.contentOffset;
    NSLog(@"x:%f, y:%f", upperLeftOfVisible.x, upperLeftOfVisible.y);
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.iv;
}

4.实现视图动画效果的,一般代码:

先像例2那样,添加多个view,再通过设置index来切换视图

- (void)changeUIView{
    [UIView beginAnimations:@"animation" context:nil];
    [UIView setAnimationDuration:1.0f];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight   forView:self.view     cache:YES];
 self.view exchangeSubviewAtIndex:2 withSubviewAtIndex:3];   //加上这句,可以有多个视图的翻页效果
    [UIView commitAnimations];
}

5.presentViewController和pushViewController的区别

UINavigationController *navController = [[UINavigationController alloc]                                         initWithRootViewController:addViewController];
[self.navigationController presentModalViewController:navController animated:YES];
[self.navigationController pushViewController:navController animated:YES];
//presentViewController: 暗示使用者需要完成某件事情,输入密码、增加资料等等,使用者必须完成或者取消,才能做其他事
//pushViewController: 则是让使用者浏览资料,使用者可以决定要前进或回到哪个页面
参考:

IOS UI:弹出视图/弹出模态 presentViewController与presentModalViewController(增加IOS 6.0说明) - sunshinexyj的专栏 - 博客频道 - CSDN.NET iOS 使用者最常看到两种切换ViewControllers 的Animations:

5.lldb中查看view的的bounds属性,应为

p (CGRect)[view bounds]
or
p view.layer.bounds
直接用 p view.bounds是查不出来的

6.屏幕旋转时使用两个视图

参考: View Controller Programming Guide for iOS: Supporting Multiple Interface Orientations

@implementation PortraitViewController
- (void)awakeFromNib{
//   首先是添加屏幕旋转时的通知
    isShowingLandscapeView = NO;
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                 selector:@selector(orientationChanged:)
                                 name:UIDeviceOrientationDidChangeNotification
                                 object:nil];
}
 
- (void)orientationChanged:(NSNotification *)notification{
    //  根据不同的屏幕布局来显示不同的控制器
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
        !isShowingLandscapeView)
    {
        [self performSegueWithIdentifier:@"DisplayAlternateView" sender:self];
        isShowingLandscapeView = YES;
    }
    else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
             isShowingLandscapeView)
    {
        [self dismissViewControllerAnimated:YES completion:nil];
        isShowingLandscapeView = NO;
    }
}

7.UIView背影设置,UIView的透明度设置 ,UITextView的圆角设置

    [super viewDidLoad];
    UIGraphicsBeginImageContext(self.view.frame.size);
    [[UIImage imageNamed:@"viewback.jpeg"] drawInRect:self.view.frame];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    self.view.backgroundColor = [UIColor colorWithPatternImage:image];
    UIView* v=[[UIView alloc] initWithFrame:self.view.frame];
    [v setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0]];
    v.bounds=CGRectMake(-50, -50, self.view.frame.size.width, self.view.frame.size.height);
    CGRect r=CGRectMake(0, 0, self.view.frame.size.width-100, self.view.frame.size.height-200);    
    UITextView* tv=[[UITextView alloc] initWithFrame:r];
    tv.text=@"asdjflajsdlfkjalskfjalskjdflasjflajsdflk\nsdkfjsadlkfjadlsfjadlsfj\n";
    tv.backgroundColor=[[UIColor grayColor] colorWithAlphaComponent:0.5];
    tv.clipsToBounds=YES;
    tv.layer.cornerRadius=10.0f;
    [v addSubview:tv];
    [self.view addSubview:v];

8.关于ios程序中图片的优化

9.ios平台对json的要求

9.如何判断点击的是不是所要的view呢?

In order to check whether certain view inside another view was touched you can use hitTest.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

In your custom implementation of touchesBegan check every touch in touches set. The point for hitTest method can be obtained using

- (CGPoint)locationInView:(UIView *)view;

method, where the view is your superView (the one that contains other views).
EDIT: Here's a fast custom implementation:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    CGPoint locationPoint = [[touches anyObject] locationInView:self]; //快速判断,相比自己用hittest来递归遍历
    UIView* viewYouWishToObtain = [self hitTest:locationPoint withEvent:event];
}

I hope this was helpful, Paul

10.关于长按手势的添加,当然需要在UIView的子类中添加

-(void)initGR{
    UILongPressGestureRecognizer *longPressGR = [[ UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
    longPressGR.minimumPressDuration = 0.7;
    [self addGestureRecognizer:longPressGR];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
    [super setSelected:selected animated:animated];
}

- (BOOL)canBecomeFirstResponder{
    return YES;
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer{
//    if([self isHighlighted])
//    {
        [[self delegate] performSelector:@selector(showMenu:) withObject:self];
//    }
}

11.获取类名字符串

NSStringFromClass([instance class]) should do the trick.
if all you want to do is test an object to see if it's a type of a certain Class
BOOL test = [self isKindOfClass:[SomeClass class]];

12.自定义UIView

+(id)autolayoutViewWithCustomization:(BOOL)customize addLabel:(BOOL)addLabel{
    UIView *view = [self new];
    view.translatesAutoresizingMaskIntoConstraints = NO;

    if (customize) {
       view.layer.cornerRadius = 4;
       view.layer.masksToBounds= YES;
       view.backgroundColor = [UIColor whiteColor];
       view.layer.borderWidth = 1;
       view.layer.borderColor = [UIColor lightGrayColor].CGColor;
    }

    if (addLabel) {
       // Create a label here
       [self addSubview:label];
    }
    return view;
}

13.一个分类在使用自定义constraints时使用

@implementation UIView (Autolayout)
+(id)autolayoutView{
    UIView *view = [self new];
    view.translatesAutoresizingMaskIntoConstraints = NO;
    return view;
}

14.水平居中,垂直居中的添加

  //下面这句是必须的,禁autoresizemask到constraints的自动翻译,以便使用自定义的constraints
    imagevew.translatesAutoresizingMaskIntoConstraints = NO;
   
    //网上看到的必须得加上图片的高度和宽度constraints才可以,试了下,不加也行
//  [imagevew addConstraint:[NSLayoutConstraint constraintWithItem:imagevew attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:200.0]];

//  [imagevew addConstraint:[NSLayoutConstraint constraintWithItem:imagevew attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:150.0]];  
    //计算公式: imagevew.attr= self.view.attr*multiplier+constant
    //垂直居中
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:imagevew attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:0.5 constant:0]];
    //水平居中
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:imagevew attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:0.5 constant:0]];
   
    //下面的程序也可以用来实现居中
    //[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imagevew attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    //水平居中
    //[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imagevew attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];

15.handle text changes for both text fields

[self.usernameTextField addTarget:self
                           action:@selector(usernameTextFieldChanged)
                 forControlEvents:UIControlEventEditingChanged];
[self.passwordTextField addTarget:self
                           action:@selector(passwordTextFieldChanged)
                 forControlEvents:UIControlEventEditingChanged];

16.设置按钮的文字尽量用 setTitle:forState 而不要用 self.originButton.titleLabel.text,要不然会带来意想不到的效果

17.stackoverflow.com/questions/2…

If the cells come from a storyboard or nib file, then initWithStyle:reuseIdentifier is not called, initWithCoder: is called instead. Here's a typical implementation of an overwritten initWithCoder::

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {
       // Do your custom initialization here
    }
    return self;
}

18.www.timoliver.com.au/2012/01/14/…

@implementation UIScrollView (ZoomToPoint)
 
- (void)zoomToPoint:(CGPoint)zoomPoint withScale: (CGFloat)scale animated: (BOOL)animated{
    //Normalize current content size back to content scale of 1.0f
    CGSize contentSize;
    contentSize.width = (self.contentSize.width / self.zoomScale);
    contentSize.height = (self.contentSize.height / self.zoomScale);
 
    //translate the zoom point to relative to the content rect
    zoomPoint.x = (zoomPoint.x / self.bounds.size.width) * contentSize.width;
    zoomPoint.y = (zoomPoint.y / self.bounds.size.height) * contentSize.height;
 
    //derive the size of the region to zoom to
    CGSize zoomSize;
    zoomSize.width = self.bounds.size.width / scale;
    zoomSize.height = self.bounds.size.height / scale;
 
    //offset the zoom rect so the actual zoom point is in the middle of the rectangle
    CGRect zoomRect;
    zoomRect.origin.x = zoomPoint.x - zoomSize.width / 2.0f;
    zoomRect.origin.y = zoomPoint.y - zoomSize.height / 2.0f;
    zoomRect.size.width = zoomSize.width;
    zoomRect.size.height = zoomSize.height;
 
    //apply the resize
    [self zoomToRect: zoomRect animated: animated];
}
@end

19.stackoverflow.com/questions/2…

20.UIScrollView各方法的调用顺序:

init-> initWithFrame->setFrame->layoutSubviews

21.UILabel自适应高度和自动换行

 //初始化label
    UILabel *label = [[UILabel alloc] init]; 
    NSString *text = @"这是一个测试!!!adsfsaf时发生发勿忘我勿忘我勿忘我勿忘我勿忘我阿阿阿阿阿阿阿阿阿阿阿阿阿啊00000000阿什顿。。。"; 
    label.text = text;
    [label setNumberOfLines:0];  
    UIFont *font = [UIFont fontWithName:@"Arial" size:14];
    //设置字体
    label.font = font;
    CGSize constraint = CGSizeMake(300, 20000.0f);
    CGSize size = [text sizeWithFont:font constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    [label setFrame:CGRectMake(10, 0, size.width, size.height)];
    [self.view addSubview:label];
 UIBarButtonItem* clearBtnItem=[[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:nil action:nil];
    UIBarButtonItem*flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem* selectAllBtnItem=[[UIBarButtonItem alloc] initWithTitle:@"全选" style:UIBarButtonItemStylePlain target:nil action:nil];
    NSArray *toolbarItemsForManagingTheSelection = @[clearBtnItem, flexibleSpace,selectAllBtnItem];
    [self setToolbarItems:toolbarItemsForManagingTheSelection animated:YES];

23.在下方显示工具栏

//    UIBarButtonItem *uploadBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
//    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
//    [self setToolbarItems:[NSArray arrayWithObjects: uploadBtn,flexItem,nil]];
//    [self.navigationController  setToolbarHidden:NO animated:YES];

24.IOS版本

    //适配iOS7uinavigationbar遮挡tableView的问题
    //    if([[[UIDevice currentDevice]systemVersion]floatValue]>=7.0)
    //    {
    //        self.edgesForExtendedLayout = UIRectEdgeNone;
    //        self.automaticallyAdjustsScrollViewInsets = NO;
    //    }

关于为什么不能使用retainCount

You should never use -retainCount, because it never tells you anything useful. The implementation of the Foundation and AppKit/UIKit frameworks is opaque; you don't know what's being retained, why it's being retained, who's retaining it, when it was retained, and so on.
For example:
* You'd think that `[NSNumber numberWithInt:1]` would have a retainCount of 1. It doesn't. It's 2.
* You'd think that @"Foo" would have a retainCount of 1. It doesn't. It's 1152921504606846975.
* You'd think that [NSString stringWithString:@"Foo"] would have a retainCount of 1. It doesn't. Again, it's 1152921504606846975.

上面的大数是2的60次方减一

Basically, since anything can retain an object (and therefore alter its retainCount), and since you don't have the source to most of the code that runs an application, an object's retainCount is meaningless.
If you're trying to track down why an object isn't getting deallocated, use the Leaks tool in Instruments. If you're trying to track down why an object was deallocated too soon, use the Zombies tool in Instruments.
But don't use -retainCount. It's a truly worthless method.
edit
Please everyone go to http://bugreport.apple.com and request that -retainCount be deprecated. The more people that ask for it, the better.
edit #2

As an update,[NSNumber numberWithInt:1] now has a retainCount of 9223372036854775807. If your code was expecting it to be 2, your code has now broken.

ref: stackoverflow.com/questions/4…

关于ios手机设备的分辨率

除了 320/480=0.6666 其余的全是: 0.5625 iphoneX

UIColor过渡

Here is a category for UIColor that can be used to linearly interpolate between two UIColors in either RGB or HSV:

@implementation UIColor (Interpolate)
+ (UIColor *)interpolateRGBColorFrom:(UIColor *)start to:(UIColor *)end withFraction:(float)f {

    f = MAX(0, f);
    f = MIN(1, f);

    const CGFloat *c1 = CGColorGetComponents(start.CGColor);
    const CGFloat *c2 = CGColorGetComponents(end.CGColor);

    CGFloat r = c1[0] + (c2[0] - c1[0]) * f;
    CGFloat g = c1[1] + (c2[1] - c1[1]) * f;
    CGFloat b = c1[2] + (c2[2] - c1[2]) * f;
    CGFloat a = c1[3] + (c2[3] - c1[3]) * f;

    return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

+ (UIColor *)interpolateHSVColorFrom:(UIColor *)start to:(UIColor *)end withFraction:(float)f {

    f = MAX(0, f);
    f = MIN(1, f);

    CGFloat h1,s1,v1,a1;
    [start getHue:&h1 saturation:&s1 brightness:&v1 alpha:&a1];

    CGFloat h2,s2,v2,a2;
    [end getHue:&h2 saturation:&s2 brightness:&v2 alpha:&a2];

    CGFloat h = h1 + (h2 - h1) * f;
    CGFloat s = s1 + (s2 - s1) * f;
    CGFloat v = v1 + (v2 - v1) * f;
    CGFloat a = a1 + (a2 - a1) * f;

    return [UIColor colorWithHue:h saturation:s brightness:v alpha:a];
}

@end

ref:stackoverflow.com/questions/2…

有图片时,使用约束的注意事项

当有图片,而又没有显式的指定的图片的大小,想依靠约束来确定的大小时,要注意图片被拉扯变形,这时,需要指定图片hug约束优先级.

If you have an existing color, you can return a new one with a specified alpha, like this:

- (void)setBackgroundColor:(UIColor *)color {
    self.backgroundColor = [color colorWithAlphaComponent:0.3f];
}

Get to UIViewController from UIView on iPhone

Using the example posted by Brock, I modified it so that its a category of UIView instead UIViewController and made it recursive so that any subview can (hopefully) find the parent UIViewController.

@interface UIView (FindUIViewController)
- (UIViewController *) firstAvailableUIViewController;
- (id) traverseResponderChainForUIViewController;
@end

@implementation UIView (FindUIViewController)
- (UIViewController *) firstAvailableUIViewController {
    // convenience function for casting and to "mask" the recursive function
    return (UIViewController *)[self traverseResponderChainForUIViewController];
}

- (id) traverseResponderChainForUIViewController {
    id nextResponder = [self nextResponder];
    if ([nextResponder isKindOfClass:[UIViewController class]]) {
        return nextResponder;
    } else if ([nextResponder isKindOfClass:[UIView class]]) {
        return [nextResponder traverseResponderChainForUIViewController];
    } else {
        return nil;
    }
}
@end

To use this code, add it into an new class file (I named mine “UIKitCategories”) and remove the class data… copy the @interface into the header, and the @implementation into the .m file. Then in your project, #import “UIKitCategories.h” and use within the UIView code:

// from a UIView subclass... returns nil if UIViewController not available

UIViewController * myController = [self firstAvailableUIViewController];

ref:stackoverflow.com/questions/1…

Drag move button

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton * btn=[[UIButton alloc]initWithFrame:CGRectMake(20, 40, 50, 50)];
    [self.view addSubview:btn];

    btn.backgroundColor=[UIColor redColor];
    [btn addTarget:self action:@selector(dragBegan:withEvent: )
      forControlEvents: UIControlEventTouchDown];
   [btn addTarget:self action:@selector(dragMoving:withEvent: )
       forControlEvents: UIControlEventTouchDragInside];
    [btn addTarget:self action:@selector(dragEnded:withEvent: )
       forControlEvents: UIControlEventTouchUpInside |
     UIControlEventTouchUpOutside];

}
- (void) dragBegan: (UIControl *) c withEvent:ev{
    NSLog(@"dragBegan......");
}

- (void) dragMoving: (UIControl *) c withEvent:ev{
    NSLog(@"dragMoving..............");
    UIButton *bt = (UIButton *)c;
    c.center = [[[ev allTouches] anyObject] locationInView:self.view];
}

- (void) dragEnded: (UIControl *) c withEvent:ev{
    NSLog(@"dragEnded..............");
    UIButton *bt = (UIButton *)c;
    c.center = [[[ev allTouches] anyObject] locationInView:self.view];
}

stackoverflow.com/questions/4…

opaque属性的真实用处

  1. 由此看来,opaque属性的真实用处是给绘图系统提供一个性能优化开关!

    按照前面的逻辑,当opaque属性被设为YES时,GPU就不会再利用图层颜色合成公式去合成真正的色值。 因此,如果opaque被设置成YES,而对应UIView的alpha属性不为1.0的时候,就会有不可预料的情况发生 UIView的alpha、hidden和opaque属性之间的关系和区别 - 王中周的个人博客 - 博客频道 - CSDN.NET

  2. 解决blended layer问题也很简单,检查红色区域view的opaque属性,记得设置成YES;检查backgroundColor属性是不是[UIColor clearColor],要知道背景颜色为clear color那可是图形性能的大敌,基本意味着blended layer是跑不了的了,为什么?自己思考一下 (默认背景颜色为1,全透明,所以需要设置一个背景颜色,如果alpha<1,那么opaque不能为yes,否则会发生颜色混乱的情况)

隐藏表格多余的分隔线

UIView *view =[ [UIView alloc]init];
view.backgroundColor = [UIColor clearColor];
[tableView setTableFooterView:view];

当页面同时存在UIScrollView和UITableView的时候,并且代理都设置为self. 那么UITableview也会调用下面的代理.

//滚动视图释放滚动
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    if([scrollView isEqual:self.conScrollView]){
        //调整顶部滑条按钮状态
        int tag = (int)scrollView.contentOffset.x/self.view.bounds.size.width +100;
        UIButton* button=(UIButton*)[self.view viewWithTag:tag];
        [button sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
}

[buttonObj sendActionsForControlEvents: UIControlEventTouchUpInside];

about iphone keychain

iphone keychain items persist after application uninstall?

Yes, this is the expected and correct behavior. Some keychain items may be shared with other apps you control (that share the same keychain item access group). You should just leave the info alone when your app is removed. You have no callback or method of removing the keychain items on deletion of your app. ref: stackoverflow.com/questions/3… keychain and provisiong profile

Note: On iPhone, Keychain rights depend on the provisioning profile used to sign your application. Be sure to consistently use the same provisioning profile across different versions of your application. Check for more information Keychain Services Programming Guide.

developer.apple.com/library/ios… stackoverflow.com/questions/1…

当一个view的高度为零的时候,它的子视图还是会显示的,如果要不显示

可以设置如下: self.tipConview.clipsToBounds=YES;

当删除UITableView中的cell时,要注意以下:

  • 1.先删除数据,再deleteRowsAtIndexPaths:WithRowAnimation
  • 2.当对应的setion,没有行时,记得把setion也给删除掉,同时numberOfSetions也要返回对应的值.
  • 3.把删除操作放在beginUpdates 和 endUpdates之间
  • 4.如果同步表格的cell和datasource,那么记得reloadData
-(void)deleteLocalRowWithIndexPath:(NSIndexPath*)indexPath{
    NSString* keyStr=[self.doingHeaderArray objectAtIndex:indexPath.section];
    NSMutableArray* arr=[self.doingDic objectForKey:keyStr];
    [self.doingTable beginUpdates];
    [arr removeObjectAtIndex:indexPath.row];
    [self.doingTable deleteRowsAtIndexPaths:@[indexPath] withRowAnimation: UITableViewRowAnimationRight];
    if(arr.count==0){
        [self.doingHeaderArray removeObjectAtIndex:indexPath.section];
        [self.doingTable deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationRight];
    }
    [self.doingTable endUpdates];
    [self.doingTable reloadData];
}

设置UITableView的选择样式.

//当调用:
[self.doingTable selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
//选择的效果,要在UITableViewCell相关类中设置.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
        if (selected) {
            self.contentView.backgroundColor=UIColorFromRGB(0xfafafa);
        } else {
            self.contentView.backgroundColor=[UIColor whiteColor];
        }
}

视图内的两个子视图作切换动画时,注意事项

如果两个子视图只是单纯的hidden切换,那么记得要加上UIViewAnimationOptionShowHideTransitionViews

    [UIView transitionWithView:_doingTable.superview duration:0.7 options:UIViewAnimationOptionTransitionCurlDown|UIViewAnimationOptionShowHideTransitionViews animations:^(void){
        _doingTable.hidden=NO;
        _historyTable.hidden=YES;
    } completion:^(BOOL finished){

    }];
});

}

    [UIView transitionWithView:_doingTable.superview duration:0.7 options:UIViewAnimationOptionTransitionCurlUp|UIViewAnimationOptionShowHideTransitionViews animations:^(void){
        _doingTable.hidden=YES;
        _historyTable.hidden=NO;
    } completion:^(BOOL finished){
    }];

正确使用convertRect:fromView:

-(void) keyboardWillShow:(NSNotification *)note{
    if(self.currentTxt!=nil&&!self.keyboardIsShow){
        CGRect keyboardBounds;
        [[note.userInfo valueFor Key:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];
        //正确的将tableviewcell中的rect,转换成上层view中的rect
        CGRect r1=[_containerView convertRect:self.currentTxt.bounds fromView:self.currentTxt];
        [UIView animateWithDuration:0.5 animations:^{
            _leaseScrollview.contentOffset=CGPointMake(0, r1.origin.y+r1.size.height+keyboardBounds.size.height-_containerView.frame.size.height+5);
        }];
    }

    self.keyboardIsShow=YES;
}

screenshot.png

禁用UITextView的copy功能

Finally solved it by subclassing UITextView (created custom class for it) and just added

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{

    if (action == @selector(copy:)){
        return NO;
    }
    return NO;
}

inside of .m file of my custom TextView subclass. After that “Copy” doesn’t appear any more with or without [menu update];

当需要单独更新某一个tableview cell的时候

-[UITableView reloadRowsAtIndexPaths:withAnimation:]
//也可以使用
[demoTableView beginUpdates];
[demoTableView endUpdates];
//来强制表格刷新.

animate a height change on a UITableViewCell when selected?

当有些方法必须在子类中实现时的解决方法

希望在两个相似的类之间公用一些代码。很容易能够想到提取父类,但是又有一些方法必须要子类实现。objective-c 没有抽象类这样的东西,只能在父类的方法里面抛异常,子类也没有提示哪些方法还没有实现,感觉很难看。于是想借用大Java的策略模式抽取protolcol然后把具体实现交给不同的对象,又觉得这样blah blah blah引入一大堆文件更加烦人。我现在还能想到的就是call back block了。objc倒是可以通过运行时动态加入方法实现类似ruby的mixin功能,但我觉得太hack了。 比如在父类的实现,插入下面的代码,来直接抛出异常:

[NSException raise:NSInternalInconsistencyException
format:@"WARNING: YOU MUST OVERRIDE THIS GETTER IN YOUR CUSTOM VIEW .M FILE"];

更改status bar

Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file. In the viewDidLoad do a [self setNeedsStatusBarAppearanceUpdate]; Add the following method:

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
}

Note: This does not work for controllers inside UINavigationController, please see Tyson’s comment below :)

stackoverflow.com/questions/1…

关于UITableView的一些用法.

[tableView scrollToRowAtIndexPath:[tView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
注意section是从0开始的.
[tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];

直接使用xib中的view:
LeaseEquMainTableViewCell* cell=[tableView dequeueReusableCellWithIdentifier:@"doingcell"];
//TODO
if(cell==nil){
NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"LeaseEquMainTableViewCell" owner:nil options:nil];
cell = (LeaseEquMainTableViewCell *)[nibs objectAtIndex:0];
}

启用UITableView的删除功能

// During startup (-viewDidLoad or in storyboard) do:
self.tableView.allowsMultipleSelectionDuringEditing = NO;


// Override to support conditional editing of the table view.
// This only needs to be implemented if you are going to be returning NO
// for some items. By default, all items are editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return YES if you want the specified item to be editable.
    return YES;
}

// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        //add code here for when you hit delete
    }    
}

stackoverflow.com/posts/33097…

自动调整lable中的font size到合适的大小

I think you just need to add this:

label.adjustsFontSizeToFitWidth = YES;
label.minimumFontSize = 0;

Then the text will automatically resize to fit the label.

Note however that this will only really work if the label.numberOfLines = 1, so that the text is on a single line. If you need the text to wrap onto multiple lines but still shrink to fit, the solution is more complex. To do this, you need to calculate the rendered size of the text and then reduce it in a loop, as follows:

NSString *theText = @"A long string";
CGRect labelRect = CGRectMake(10, 50, 300, 50);
label.adjustsFontSizeToFitWidth = NO;
label.numberOfLines = 0;

CGFloat fontSize = 30;
while (fontSize > 0.0){
    CGSize size = [theText sizeWithFont:[UIFont fontWithName:@"Verdana" size:fontSize] constrainedToSize:CGSizeMake(labelRect.size.width, 10000) lineBreakMode:UILineBreakModeWordWrap];

    if (size.height <= labelRect.size.height) break;

    fontSize -= 1.0;
}

//set font size
label.font = [UIFont fontWithName:@"Verdana" size:fontSize];

给textview创建placeholder

uilabel keypath Easy way, just create placeholder text in UITextView by using the following UITextViewDelegate methods:

- (void)textViewDidBeginEditing:(UITextView *)textView{
    if ([textView.text isEqualToString:@"placeholder text here..."]) {
         textView.text = @"";
         textView.textColor = [UIColor blackColor]; //optional
    }
    [textView becomeFirstResponder];
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
    if ([textView.text isEqualToString:@""]) {
        textView.text = @"placeholder text here...";
        textView.textColor = [UIColor lightGrayColor]; //optional
    }
    [textView resignFirstResponder];
}

just remember to set myUITextView with the exact text on creation e.g.

UITextView *myUITextView = [[UITextView alloc] init];
myUITextView.delegate = self;
myUITextView.text = @"placeholder text here...";
myUITextView.textColor = [UIColor lightGrayColor]; //optional

and make the parent class a UITextViewDelegate before including these methods e.g.

@interface MyClass () <UITextViewDelegate>
@end

stackoverflow.com/questions/1…

反转数组

There is a much easier solution, if you take advantage of the built-in reverseObjectEnumeratormethod on NSArray, and the allObjects method of NSEnumerator:

NSArray* reversedArray = [[startArray reverseObjectEnumerator] allObjects];

Because allObjects is documented as returning an array with the objects that have not yet been traversed with nextObject, it strongly implies that those objects will be delivered in order of the enumerator. It even points out that after calling allObjects, the next object on the enumerator will be nil

_statusArray=@[@"申请中",@"申请审核通过", @"申请审核不通过", @"同意发放", @"不同意发放",@"送货中", @"租赁中", @"续租申请",@"续租中",@"续租审核不通过",@"回收申请",@"确认回收"];
NSInteger statusInt=detailInfo.zlzt.integerValue;
NSArray* tempStatusArr=[self.statusArray subarrayWithRange:NSMakeRange(0, statusInt)] ;
NSPredicate* pred=[NSPredicate predicateWithFormat:@"NOT SELF CONTAINS '不'"];
NSArray* tempArr=[tempStatusArr filteredArrayUsingPredicate:pred];
NSArray* reversedArray = [[tempArr reverseObjectEnumerator] allObjects];

UIButton是需要自己设置选中状态的

在IB中,设置选中状态,但实际运行无法被选中,需要自己代码来处理. just set selected when you call the method on button click event.. for example..

-(IBAction) btnCheckBoxMale_Clicked:(id)sender{
    [btnCheckBoxMale setSelected:YES];
}

错误: Cell animation stop fraction must be greater than start fraction的解决方法

I experienced the same crash when trying to use a dummy footer to remove potential “empty” table view cells. The solution was to get rid of

tableView:viewForFooterInSection:
tableView:heightForFooterInSection:

and replace them with the following, in viewDidLoad :

tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];

Yes i also face this type of problem,do one thing just remove footer view.

stackoverflow.com/questions/1…

Tell UIScrollView to scroll to the top

UPDATE FOR iOS 7

[self.scrollView setContentOffset:
    CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];

ORIGINAL

[self.scrollView setContentOffset:CGPointZero animated:YES];

or if you want to preserve the horizontal scroll position and just reset the vertical position:

[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0) animated:YES];

stackoverflow.com/questions/9…

OC中声明指针时注意情况

You should declare your constant string as follows:

NSString * const kSomeConstantString = @""; // constant pointer

instead of:

const NSString * kSomeConstantString = @""; // pointer to constant
// equivalent to
NSString const * kSomeConstantString = @"";

The former is a constant pointer to an NSString object, while the later is a pointer to a constant NSString object.

Using a NSString * const prevents you from reassigning kSomeConstantString to point to a different NSString object. The method isEqualToString: expects an argument of type NSString . If you pass a pointer to a constant string (const NSString ), you are passing something different than it expects. Besides, NSString objects are already immutable, so making them const NSString is meaningless. stackoverflow.com/questions/6…

UITableView的cell之间增加空隙的话,要么设置一下footer,要么就是在cell上留出多余的空间

- (CGFloat)tableView:(UITableView*)tableView
heightForFooterInSection:(NSInteger)section {
return 5.0;
}

设置UITableView cell选择时的高亮

You can do this as follows. Set your table cell’s selection style to UITableViewCellSelectionStyleNone. This will remove the blue background highlighting. Then, to make the text label highlighting work the way you want, instead of using the default UITableViewCell class, create a subclass of UITableViewCell and override the default implementation of setHighlighted:animated with your own implementation that sets the label colors to however you want depending on the highlighted state.

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
    if (highlighted) {
        self.textLabel.textColor = [UIColor whiteColor];
    } else {
        self.textLabel.textColor = [UIColor blackColor];
    }
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:sMenuStoreCell
    forIndexPath:indexPath];

    // configure your cell here

    // this is where you set your color view
    UIView *customColorView = [[UIView alloc] init];
    customColorView.backgroundColor = [UIColor colorWithRed:180/255.0
    green:138/255.0
    blue:171/255.0
    alpha:0.5];
    cell.selectedBackgroundView = customColorView;
    return cell;
}

设置长按手势

if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
[self.doingTable selectRowAtIndexPath:indexPath
animated:NO
scrollPosition:UITableViewScrollPositionNone];

48.Should IBOutlets be strong or weak under ARC?

Summarized from the developer library: From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because: Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership. The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet).

@property (weak) IBOutlet MyView *viewContainerSubview;
@property (strong) IBOutlet MyOtherClass *topLevelObject;

Patterns for Managing Outlets Become Consistent Across Platforms

The patterns for declaring outlets in iOS and OS X change with ARC and become consistent across both platforms. The pattern you should typically adopt is: outlets should be weak, except for those from File’s Owner to top-level objects in a nib file (or a storyboard scene) which should be strong. Full details are given in Nib Files in Resource Programming Guide. ref: stackoverflow.com/questions/7… stackoverflow.com/questions/2… developer.apple.com/library/ios…

47.Whats the difference between sizeToFit, sizeThatFits, and sizeWithAttributes?

When sizing a UILabel to fit, what’s the difference between the 3 following methods of doing it:

1 -CGSize size = [string sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];
CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));
2 - [label sizeToFit]
3 - [label sizeThatFits..]
sizeToFit can make UILabel relayout its bounds based on it’s contents.
sizeThatFit can calculate the size of UILabel’s contents.
sizeWithAttributes can calculate a string’s size with attributes you passed.
[self.tableview registerclass:[uitableviewcell class] forcellreuseidentifier:viewcontrollercellreuseidentifier];
uiview *view = [[uiview alloc] initwithframe:cgrectmake(100, 100, 200, 100)];
view.backgroundcolor = [uicolor yellowcolor];
uilabel *label = [[uilabel alloc] initwithframe:cgrectmake(5, 5, 0, 0)];
[label setfont:[uifont systemfontofsize:20]];
label.text = @"hello wdszgrf";
cgsize sizethatfits = [label sizethatfits:cgsizezero];
nslog(@"---- %f  %f ----", sizethatfits.width, sizethatfits.height);
// output:  ---- 117.000000  24.000000 ----

nslog(@"**** %f  %f ****", label.frame.size.width, label.frame.size.height);
// output:  **** 0.000000  0.000000 **** 说明sizethatsize并没有改变原始label的大小

[label sizetofit];  // 这样搞就直接改变了这个label的宽和高,使它根据上面字符串的大小做合适的改变
[label setcenter:cgpointmake(80, 50)];
nslog(@"==== %f %f ====", label.frame.size.width, label.frame.size.height);
// output:   ==== 117.000000 24.000000 ====

[view addsubview:label];
[self.view addsubview:view];

46. UICollectionView: must be initialized with a non-nil layout parameter

The crash is telling you pretty explicitly what is going wrong:

UICollectionView must be initialized with a non-nil layout parameter. If you check the Apple documentation for UICollectionView, you'll find that the only initializer is initWithFrame:collectionViewLayout:. Further, in the parameters for that initializer, you'll see:

frame
The frame rectangle for the collection view, measured in points. The origin of the frame is relative to the superview in which you plan to add it. This frame is passed to the superclass during initialization.
layout
The layout object to use for organizing items. The collection view stores a strong reference to the specified object. Must not be nil.

I've bolded the important part. You must use initWithFrame:collectionViewLayout: to initialize your UICollectionView, and pass it a non-nil UICollectionViewLayout object. One way to fix this, then, would be to simply change the order of initialization you do:

UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(100, 100);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
[self.collectionView registerClass:[CollectionCell class] forCellWithReuseIdentifier:@"cell"];

45.present的过程:

1)presenting view 寻找其根视图(window除外),
2)presenting view(根视图) 和presented view 一同被放到 UITransitionView进行动画切换。
3)动画完成时,presenting view(根视图)从视图体系中移除,presented view添加到window上。

结论:
1)presenting view 的父视图 是window,并且覆盖整个window2)原视图栈在present完成后,会整体移除,window除外。
presentViewController

44复杂时间串的解析

image.png

NSString* string = @"Wed, 3 Apr 2013 04:11:02 GMT";
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
[inputFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss Z"];
NSDate* inputDate = [inputFormatter dateFromString:string];
NSLog(@"date = %@", inputDate);

//上面可能会看到Locale,这个是干什么的呢?据网上资料说是为了适应中文环境,要不然会识别不出Wed这类的,要是英文环境就不用。大概就是这个意思吧。大家可以试着注释掉这两个Locale语句,发现真的不可以哦。

NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setLocale:[NSLocale currentLocale]];
[outputFormatter setDateFormat:@"HH:mm:ss"];
NSString *str = [outputFormatter stringFromDate:inputDate];
NSLog(@"testDate:%@", str);
1. G: 公元时代,例如AD公元  
2. yy: 年的后2位  
3. yyyy: 完整年  
4. MM: 月,显示为1-12  
5. MMM: 月,显示为英文月份简写,如 Jan  
6. MMMM: 月,显示为英文月份全称,如 Janualy  
7. dd: 日,2位数表示,如02  
8. d: 日,1-2位显示,如 2  
9. EEE: 简写星期几,如Sun  
10. EEEE: 全写星期几,如Sunday  
11. aa: 上下午,AM/PM  
12. H: 时,24小时制,0-23  
13. K:时,12小时制,0-11  
14. m: 分,1-2位  
15. mm: 分,2位  
16. s: 秒,1-2位  
17. ss: 秒,2位  
18. S: 毫秒  
19. Z:GMT  

常用的时间格式有:

1. yyyy-MM-dd HH:mm:ss.SSS  
2. yyyy-MM-dd HH:mm:ss  
3. yyyy-MM-dd  
4. MM dd yyyy   

43.问题:

正常情况下,只有在新机器第一次安装,IOS操作系统会询问你是否开启远程通知.那么如果用户选择了,不接受的话,用户想再次接收推送,就只能到IOS系统设置里面去开启了. 针对这种情况,目前app没有相应的处理措施.

方案:

1.在上述情况下,如果用户在app设置里面开启推送的话,提示自己到IOS系统设置里面去开启对应app的推送.
2.当用户在用户IOS系统设置里开启推送之后,app会立即得到deviceToken,这时,将deviceToken实时传给服务器.

相关条目,请见:23

42.获取view的截图

Problem: You want to take a snapshot of a UIView as a UIImage.

Solution: It's sometimes useful to create a UIImageView representing a visual snapshot of another UIView object. This new UIImageView can be useful for animation.

UIView *subView = self.viewWithManySubViews;
UIGraphicsBeginImageContextWithOptions(subView.bounds.size, YES, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[subView.layer renderInContext:context];
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *snapshotImageView = [[UIImageView alloc] initWithImage:snapshotImage];

屏幕外的,利用window,自行百度

41.拖动手势动画

The kind of effects that you are describing as simulating a king of gravity/inertia can be produced by means of ease-out (start fast, end slow) and ease-in (start slow, end fast) timing functions. Support for easing out and easing in is available in iOS, so I don't think you need any external library nor hard work (although, as you can imagine, your effect will need a lot of fine tuning). This will animate the translation of an object to a given position with an ease-out effect:

 [UIView animateWithDuration:2.0 delay:0
         options:UIViewAnimationOptionCurveEaseOut
         animations:^ {
               self.image.center = finalPosition;
   }completion:NULL];

If you handle your gesture through a UIPanGestureRecognizer, the gesture recognizer will provide you with two important information to calculate the final position: velocity and translation, which represent respectively how fast and how much the object was moved. You can install a pan gesture recognizer in your view (this would be the object you would like to animate, I guess) like this:

UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
[yourView addGestureRecognizer:panGestureRecognizer];
        [panGestureRecognizer release];

And then handle the animation in your handler:

 -(void)handlePanFrom:(UIPanGestureRecognizer*)recognizer {
    CGPoint translation = [recognizer translationInView:recognizer.view];
    CGPoint velocity = [recognizer velocityInView:recognizer.view];

    if (recognizer.state == UIGestureRecognizerStateBegan) {    
    } else if (recognizer.state == UIGestureRecognizerStateChanged) {
        <track the movement>
    } else if (recognizer.state == UIGestureRecognizerStateEnded) {
        <animate to final position>
    }
 }

shareimprove this answer

40.Format string, integer with leading zeros

Use the format string "img_%03d.jpg" to get decimal numbers with three digits and leading zeros.

39.'NSUnknownKeyException' … setValue:forUndefinedKey:]: …not key value coding compliant

主要是由于在IB中连线的属性,在对应的代码中的属性消失了或名称发生变化了,那么运行时,就会发生相应的 错误.

stackoverflow.com/questions/1…

37.苹果的view布局有所变化,现在view默认是全屏模式,而所有的bar(navigation bar, tool bar, search bars 与scope bars都是半透明),status bar则是全透明。

In iOS7, UINavigationBar has a translucent property. By this, the view of the child VC of UINavigationViewController is under UINavigationBar by default. If you don't need to get an translucent effect, turn off this property using the following code.

self.navigationController.navigationBar.translucent = NO

36.QuickLook功能

Apple introduced a nice feature called Quick Look in Leopard. With just a hit on the spacebar (or the combination of Command + Y), users could ‘peek’ into the selected file in the Finder (or some other application).

35.Xcode 6的iOS模拟器的应用目录的变化。

Xcode 5的iOS模拟器的应用的目录是在~/Library/Application Support/iPhone Simulator/<iOS_Version>/Applications/{Application_ID}

Xcode 6的目录改为~/Library/Developer/CoreSimulator/Devices/{Device_ID}/data/Containers/Bundle/Application/{Application_ID}/

这里的Device_ID和Application_ID都是一串UUID,如果想查找不同的模拟器``对应的Device_ID,可以通过在Terminal执行命令xcrun simctl list

34.为什么这里需要copy

@interface SomeClass : NSObject
@property (nonatomic, retain) NSString* text;
@end
...
SomeClass* test = [[SomeClass alloc] init];
NSMutableString* string = [[NSMutableString alloc] initWithString:@"cat"];
//因为NSString是NSMutableString的基类,所以可以直接set
[test setText:string];
//这时改变string的值,会影响到上面test实例中text属性的值,而这不是所预期的行为.
[string appendString:@"dog"];

所以要改成:

@property (nonatomic, copy) NSString* text;

ref:

33.关于属性的合成.

@interface Counter : NSObject
@property (nonatomic, retain) NSNumber *count;
@end;

The property declares two accessor methods. Typically, you should ask the compiler to synthesize the methods; however, it’s instructive to see how they might be implemented.

In the “get” accessor, you just return the synthesized instance variable, so there is no need for retain or release:

- (NSNumber *)count {
    return _count;
}

In the “set” method, if everyone else is playing by the same rules you have to assume the new count may be disposed of at any time so you have to take ownership of the object—by sending it a retain message—to ensure it won’t be. You must also relinquish ownership of the old count object here by sending it a release message. (Sending a message to nil is allowed in Objective-C, so the implementation will still work if _count hasn’t yet been set.) You must send this after [newCount retain] in case the two are the same object—you don’t want to inadvertently cause it to be deallocated.

- (void)setCount:(NSNumber *)newCount {
    [newCount retain];
    [_count release];
    // Make the new assignment.
    _count = newCount;
}

Don’t Use Accessor Methods in Initializer Methods and dealloc The only places you shouldn’t use accessor methods to set an instance variable are in initializer methods and dealloc. To initialize a counter object with a number object representing zero, you might implement an init method as follows:

- init {
self = [super init];
if (self) {
    _count = [[NSNumber alloc] initWithInteger:0];
}
return self;
}

blog.sina.com.cn/s/blog_55a8…

32.deviceToken在什么时候发生变化?

By requesting the device token and passing it to the provider every time your application launches, you help to ensure that the provider has the current token for the device. If a user restores a backup to a device other than the one that the backup was created for (for example, the user migrates data to a new device), he or she must launch the application at least once for it to receive notifications again. If the user restores backup data to a new device or reinstalls the operating system, the device token changes. Moreover, never cache a device token and give that to your provider; always get the token from the system whenever you need it

ref: stackoverflow.com/questions/6…

31. layer.cornerRadius 这个值是怎么算得

应该取rect.size.width/2吧,就是正方行边长的一半。
四个角的圆角其实都是四分之一的圆,这个圆的半径就是 cornerRadius
圆角的圆弧其实就是与两个边正切的圆的一小部分。
对于正方形而言,形成一个圆就是一个内切圆。
画一下就明白了。

30.使用NSJSONSerialization,可以分析各种复杂格式json数据。

使用的类方法是

+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error。

根据不同data的结构,设置不同的option。这里option有三类:NSJSONReadingMutableContainersNSJSONReadingMutableLeaves , NSJSONReadingAllowFragments。
apple文档对这三种方法做了说明。
1NSJSONReadingMutableContainers
Specifies that arrays and dictionaries are created as mutable objects.//指定数组和字典作为可变对象创建。
2NSJSONReadingMutableLeaves
Specifies that leaf strings in the JSON object graph are created as instances of NSMutableString.//指定在JSON对象图叶字符串创建实例NSMutableString。
3NSJSONReadingAllowFragments
Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.//指定解析器应该允许最上级对象不是数组或者NSDictionary的实例。

Available in iOS 5.0 and later.

demo:
NSData *dictData2 = [@"{ \"foo\": \"bar\" }" dataUsingEncoding:NSUTF8StringEncoding];
id dict2 = [NSJSONSerialization JSONObjectWithData:dictData2 options:NSJSONReadingMutableContainers error:NULL];
NSLog(@"%@", [dict2 class]);
NSLog(@"%@", [dict2 superclass]);
NSLog(@"%d", [dict2 isKindOfClass:[NSMutableDictionary class]]);
输出:
__NSDictionaryM
NSMutableDictionary
1

下面使用参数NSJSONReadingAllowFragments,才能解析出. top level object是个字符串.

NSString *jsonString = @"\"test\"";
NSData* data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
NSLog(@"result %@", result);

ref:stackoverflow.com/questions/9…

29.UIPasteboard

The UIPasteboard class enables an app to share data within the app and with another app. To share data with any other app, you can use system-wide pasteboards; to share data with another app that has the same team ID as your app, you can use app-specific pasteboards. Apps can also create pasteboards for their own use or for use by other apps that have the same team ID. A pasteboard must be identified by a unique name. You may also mark an app-specific pasteboard as persistent, so that it continues to exist past the termination of the app and past system reboots. System pasteboards are persistent by default. developer.apple.com/library/ios…

28.关于openUDID的一些说法:

They do NOT use the keychain, they use the UIPasteBoard, which is a shared OS construct that persists across device restarts. From the doc: "system pasteboards are persistent across device restarts, application uninstalls, and restores." developer.apple.com/library/ios…

This seems to have changed, the docs now say "When a pasteboard is persistent, it continues to exist past app terminations and across system reboots. App pasteboards that are not persistent only last until the owning (creating) app quits. System pasteboards are persistent. App pasteboards by default are not persistent. A persistent app pasteboard is removed when the app that created it is uninstalled." meaning that no pastebards survive app uninstalls. Maybe keychain is better, but I cannot find any definitive (coming from Apple) documentation about this. – Andreas Paulsson Sep 20 '13 at 7:37 ref:stackoverflow.com/questions/9… stackoverflow.com/questions/1…