美文网首页
iOS 小知识

iOS 小知识

作者: 鄙人哈哈哈哈5871 | 来源:发表于2016-07-18 22:17 被阅读155次

    1代码中字符串换行

    ​NSString *string = @"ABCDEFGHIJKL" \

    ​"MNOPQRSTUVsWXYZ";

    ​2没有用到类的成员变量的,都写成类方法

    ​3category可以用来调试可以隐藏私有方法,最主要的是用它截住函数。

    ​例1:测试时我想知道TableViewCell有没有释放,就可以这样写

    ​@implementationUITableViewCell(dealloc)

    -(void)dealloc  {

    NSLog(@"%@",NSStringFromSelector(_cmd));

    ​NSArray *array = allSubviews(self);

    ​// allSubviews是cookBook里的函数,可以取一个view的所有subView ,在这个文档后面也有

    NSLog(@"%@",array);

    [super dealloc];

    }

    @end

    例2:我调试程序,觉得table的大小变了,想找到在哪改变的,这样做:@implementation UITableView(set frame)

    -(void)setFrame:(CGRect)frame {

    NSLog(%"%@",self);[super setFrame: frame];

    }

    @end

    ​category和exension的区别:

    ​category:

    ​a.类别是一种为现有的类添加新方法的方式。利用Objective-C的动态运行时分配机制,Category提供了一种比继承(inheritance)更为简洁的方法来对class进行扩展,无需创建对象类的子类就能为现有的类添加新方法,可以为任何已经存在的class添加方法,包括那些没有源代码的类(如某些框架类)。

    ​b.声明类别

    ​@interface NSArray (MArrayCateoryDemo)

    ​-(NSArray*) orderByTime;

    ​@end

    ​实现类别

    ​@implementation NSArray (MArrayCateoryDemo)

    ​-(NSArray*) orderByTime {

    ​NSArray *demo = [self ...];

    ​return demo;

    ​}

    ​@end

    ​调用:NSArray * array = ..;NSArray = [array orderByTime];

    ​三、类别的局限性有两方面局限性:

    ​(1)无法向类中添加新的实例变量,类别没有位置容纳实例变量。

    ​(2)名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具有更高的优先级。类别方法将完全取代初始方法从而无法再使用初始方法。

    ​c 类别的作用类别主要有3个作用:

    ​(1)可以将类的实现分散到多个不同文件或多个不同框架中,方便代码管理。也可以对框架提供类的扩展(没有源码,不能修改)。

    ​(2)创建对私有方法的前向引用:如果其他类中的方法未实现,在你访问其他类的私有方法时编译器报错这时使用类别,在类别中声明这些方法(不必提供方法实现),编译器就不会再产生警告

    ​(3)向对象添加非正式协议:创建一个NSObject的类别称为“创建一个非正式协议”,因为可以作为任何类的委托对象使用。

    ​5. extension

    ​@interface MyObject()

    {

    ​int extension;

    ​}

    ​-(void)testInExtension;

    ​@end

    ​他们的主要区别是:

    ​1、形式上来看,extension是匿名的category。

    ​2、extension里声明的方法需要在mainimplementation中实现,category不强制要求。

    ​3、extension可以添加属性(变量),category不可以。

    ​6. block声明 blockvoid(^blockDemo)(void);

    ​定义blockblockDemo = ^{...};

    ​声明和定义在一起void(^blockDemo)(void) = ^ {...};

    ​前面一个void是返回值类型,后面括号里面void是参数类型,此例中表明没有返回值和参数。

    ​如何使用举例:比如请求网络数据,声明一个block用来传递请求到的数据:void(^requestData)(NSData *id);定义一个获取数据的方法

    ​- (void)requestDataWithBlock:(void (^)(NSData* data))pBlock {

    ​NSData *data = [NSData data];

    ​pBlock(data);

    ​}

    ​调用该方法去获取数据。

    ​[self requestDataWithBlock:^(NSData *data) {

    ​if (data) {...} else {...}

    ​}];

    ​为了延长block的生命周期,可以将其声明为类的成员变量。

    ​typedef void(^blockDemo)(void);

    ​@interface MyObject() {blockDemo demoBlock;}@end

    ​很需要注意的一点就是,block内local variable是會自動做retain的, 而用到的外部成员也会自动retain, 而這就很容易造成retain cycle。为了解决这个问题,在使用外部成员时都应该在使用之前加上__block。

    ​7.使用自定义字体

    ​1.添加对应的字体(.ttf或.odf)到工程的resurce,例如my.ttf。

    ​2.在info.plist中添加一项 Fonts provided by application (item0对应的value为my.ttf,添加多个字体依次添加就可以了)。

    ​3.使用时aLabel.font=[UIFontfontWithName:@"XXX" size:30]; 注意XXX不一定是my,这里是RETURN TO CASTLE。可以用如下方法查看familyname和font name:

    ​NSArray *familyNames = [UIFontfamilyNames];

    ​for( NSString *familyNameinfamilyNames ){

    ​printf( "Family: %s \n", [familyNameUTF8String] );

    ​NSArray *fontNames = [UIFontfontNamesForFamilyName:familyName];

    ​for( NSString *fontNameinfontNames ){

    ​printf( "\tFont: %s \n", [fontNameUTF8String] );

    ​}}

    ​8后台运行IOS允许长时间在后台运行的情况有7种:

    ​audio

    ​VoIP

    ​GPS

    ​下载新闻

    ​和其它附属硬件进行通讯时

    ​使用蓝牙进行通讯时

    ​使用蓝牙共享数据时

    ​除以上情况,程序退出时可能设置短暂运行10分钟

    ​9 关于UITableView

    ​任意设置Cell选中状态的背景色:

    ​UIView *bgView = [[UIView alloc] init];

    ​bgView.backgroundColor = [UIColor orangeColor];

    ​self.selectedBackgroundView = bgView;[bgView release];

    ​该方法设置的是纯色, 也可以使用任何图片,把selectedBackgroundView设成UIImageView。但要注意,选中取消时,需要取消颜色,self.selectedBackgroundView = nil,否则颜色一直在。除了上面的方法,前几天发现了一个新方法:重写UITableViewCell 的setSelected:animated:方法

    -(void)setSelected:(BOOL)selected animated:(BOOL)animated{

    ​[super setSelected:selected animated:animated];

    ​if (selected) {

    ​self.backgroundColor = RGB(224, 152, 40);

    ​}else {

    self.backgroundColor = [UIColor clearColor];

    ​}

    }

    ​flashScrollIndicators这个很有用,闪一下滚动条,暗示是否有可滚动的内容。可以在ViewDidAppear或[table reload]之后调用。

    ​点击Cell中的按钮时,如何取所在的Cell:

    ​-(void)OnTouchBtnInCell:(UIButton *)btn {

    ​CGPoint point = btn.center;

    point = [table convertPoint:point fromView:btn.superview];

    NSIndexPath* indexpath = [table indexPathForRowAtPoint:point];UITableViewCell *cell = [table cellForRowAtIndexPath:indexpath];

    ...// 也可以通过一路取btn的父窗口取到cell,但如果cell下通过好几层subview才到btn,就要取好几次 superview// 所以我用上面的方法,比较通用。这种方法也适用于其它控件。 }

    ​10. 理解@selector()

    ​可以理解 @selector()就是取类的成员方法的编号,他的行为基本可以等同C语言的中函数指针,只不过C语言中,可以把函数名直接赋给一个函数指针,而Object-C的类不能直接应用函数指针,这样只能做一个@selector语法来取.

    ​它的结果是一个SEL类型。这个类型本质是类方法的编号(函数地址)可以声明一个SEL类型的变量。如:SEL _MyMethod;SEL一般用作参数传递, 以下这个简单的例子便是系统中使用@selector的场景和原理,比如给自定义控件或者XIB中的控件关联事件相应方法,基本上就是这样做的,熟悉掌握@selector的原理和流程,可以为我们的编程带来极大的便利。

    ​@interface A : NSObject {

    ​SEL _AMehtod;

    ​Other_Class_Instance id;

    ​}

    ​- (void)popUpAWarningDialogWithTarget:(id)pTarget seelctor:(SEL)pSel;

    ​@end

    ​@implementA

    ​- (void)popUpAWarningDialogWithTarget:(id)pTarget seelctor:(SEL)pSel {

    ​id = pTarget;

    ​_AMethod = pSel;

    [self handleSelecter];

    ​}

    - (void)handleSelect {

    ​if ([id respondsToSelector:_AMethod]) {

    ​[id performSelector:_AMethod];

    ​}

    ​}

    ​@end

    ​@interface B:NSObject{

    ​A *_a;

    ​}

    ​@end

    ​@implement B

    ​- (void)testSelector {

    ​_a = [A alloc] init];

    ​[_a popUpAWarningDialogWithTarget:selfseelctor:@selector(pupUpDialog)];

    ​}

    ​- (void)pupUpDialog {

    ​NSLog(@"It's called!");

    ​}

    ​@end

    ​11.一个不停震动的方法:// 定义一个回调函数,震动结束时再次发出震动

    ​void MyAudioServicesSystemSoundCompletionProc (SystemSoundIDssID,void *clientData){

    ​BOOL* iShouldKeepBuzzing = clientData;

    ​if (*iShouldKeepBuzzing) {AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

    ​} else {

    ​//Unregister, so we don't get called again...AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);

    ​}

    }以下为调用的代码:

    ​BOOL iShouldKeepBuzzing = YES;

    ​AudioServicesAddSystemSoundCompletion (kSystemSoundID_Vibrate,NULL,NULL,MyAudioServicesSystemSoundCompletionProc,&iShouldKeepBuzzing );

    ​AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

    ​12去掉app图标的发光效果info.plist里增加Icon already includes gloss effects,值设为YES ]

    ​13UIColor colorWithRed:green:blue:alpha:这个方法的参数必须用浮点型。假如使用Xcode自带的取颜色的工具,取到的RGB值分别为:25,25,25,传给上述方法的参数应为25/255.0或25.0/255。如果用整型25/255,经过取整,小数部分没有了,显示出来的颜色和取到的是不一样的。可以定义一个宏:

    ​#define RGB(A,B,C) [UIColor colorWithRed:A/255.0 green:B/255.0 blue:C/255.0 alpha:1.0]

    ​然后用RGB(25,25,25)就可以了

    ​14禁止textField和textView的复制粘贴菜单:

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

    ​if ([UIMenuController sharedMenuController]) {

    ​[UIMenuController sharedMenuController].menuVisible = NO;

    ​}

    ​return NO;

    ​}

    ​15loadView如果重载loadView,一定要在这个方法里产生一个self.view。可以调用[super loadView],也可以使用alloc+init。因为在该函数时,self.view为nil,如果直接调用self.member的话,也就是loadView不断调用loadView,进入了死循环 。

    ​16如何进入软件在app store 的页面:先用iTunes Link Maker找到软件在访问地址,格式为itms-apps://ax.itunes.apple.com/...,

    然后#defineITUNESLINK@"itms-apps://ax.itunes.apple.com/..."

    ​NSURL *url = [NSURL URLWithString:ITUNESLINK];

    ​if([[UIApplication sharedApplication] canOpenURL:url]){

    ​[[UIApplication sharedApplication] openURL:url];}

    ​如果把上述地址中itms-apps改为http就可以在浏览器中打开了。可以把这个地址放在自己的网站里,链接到app store。iTunes Link Maker地址:http://itunes.apple.com/linkmaker

    ​17禁止程序运行时自动锁屏[[UIApplication sharedApplication] setIdleTimerDisabled:YES];

    ​18改变UIAlertView背景UIAlertView默认是半透明的,会透出背景的内容,有时看着有些混乱。可以写个改变背景的方法changeBackground。

    @interfaceUIAlertView (changeBK)

    - (void)changeBackground;

    @end

    ​@implementationUIAlertView (changeBK)

    - (void)changeBackground{

    for(UIView* vin[selfsubviews]){

    ​if([visKindOfClass:[UIImageView class]]) {

    ​UIImage*theImage = [UIImageimageNamed:@"AlertView.png"];((UIImageView*)v).image= theImage;

    ​break;

    ​}

    }

    }

    @end

    在[alertView show]之后或willPresentAlertView:中调用即可。// UIAlertView *alertView = [UIAlertView alloc] init ......[alertView show];[alertView changeBackgro

    ​19 改变UITextField的背景可以给textField加好看的边框等

    ​@interface UITextField (changeBK)

    -(void)orangeBackground;

    @end@implementation UITextField (changeBK)

    -(void)orangeBackground{

    self.background = [[UIImage imageNamed:@"fieldBK.png"]stretchableImageWithLeftCapWidth:5 topCapHeight:5];}

    @end

    ​20取常用的地址Document:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    ​NSString *documentsDirectory = [paths objectAtIndex:0];

    ​Library:

    ​NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);

    ​NSString *libraryDirectory = [paths objectAtIndex:0];

    ​​21如何改变UINavigationBar的背景针对较旧的IOS,大概是IOS 4.3及以下:@implementation UINavigationBar (CustomImage)- (void)drawRect:(CGRect)rect{UIImage *image = [[UIImage imageNamed: @"navBar"] stretchableImageWithLeftCapWidth:5 topCapHeight:0];[image drawInRect:CGRectMake(0, 0.5, self.frame.size.width, self.frame.size.height)];}@end

    ​针对所有版本IOS:@implementation UINavigationBar (selBackground)

    ​-(void)setToCustomImage{

    ​if ([[UIDevice currentDevice] systemVersion].floatValue >= 5.0 ) {

    ​[self setBackgroundImage:[UIImage imageNamed:@"navBar"] forBarMetrics:UIBarMetricsDefault];

    }else{

    ​self.layer.contents = (id)[UIImage imageNamed:@"navBar"].CGImage;}}

    ​@end

    ​22自IOS 6.0,为了控制旋转,要给UINavigationController写个category(原因见以下黄色背景的内容)

    ​@interface UINavigationController (Rotate)

    ​@end

    ​@implementation UINavigationController (Rotate)

    ​- (NSUInteger)supportedInterfaceOrientations{

    ​return [self.topViewController supportedInterfaceOrientations];

    ​}

    ​- (BOOL)shouldAutorotate{

    ​return [self.topViewController shouldAutorotate];}

    ​@end

    ​23简化代码用的define

    ​#define SETRGBSTROKECOLOR(ctx,R,G,B) CGContextSetRGBStrokeColor(context, R/255.0, G/255.0, B/255.0, 1.0)

    ​#define SETRGBFILLCOLOR(ctx,R,G,B) CGContextSetRGBFillColor(context, R/255.0, G/255.0, B/255.0, 1.0)

    ​#define _ADDOBSERVER(TITLE, SELECTOR) [[NSNotificationCenter defaultCenter] addObserver:self selector:SELECTOR name:TITLE object:nil]

    ​#define _REMOVEOBSERVER(id) [[NSNotificationCenter defaultCenter] removeObserver:id]

    ​#define _POSTNOTIFY(TITLE,OBJ,PARAM) [[NSNotificationCenter defaultCenter] postNotificationName:TITLE object:OBJ userInfo:PARAM]

    ​24 如何加大按钮的点击范围:

    ​1.把UIButton的frame 设置的大一些,然后给UIButton设置一个小些的图片[tmpBtn setImageEdgeInsets:UIEdgeInsetsMake(5, 5, 5, 5)];// 注意这里不能用setBackgroundImage[tmpBtn setImage:[UIImage imageNamed:@"testBtnImage"] forState:UIControlStateNormal];

    ​2.使用类UIButton (hitTest)。这是一个开源类

    ​25 有时iPhone或iPad检测设备旋转不准确加上这个通知就可以了:_ADDOBSERVER(UIDeviceOrientationDidChangeNotification, @selector(didRotateNotification));

    相关文章

      网友评论

          本文标题:iOS 小知识

          本文链接:https://www.haomeiwen.com/subject/krhmjttx.html