美文网首页iOS tips
iOS开发小技巧

iOS开发小技巧

作者: 深山问 | 来源:发表于2016-01-11 17:48 被阅读269次
    • [去掉和修改UISearchBar 默认的背景色(灰色)和TextField颜色](#去掉和修改UISearchBar 默认的背景色(灰色)和TextField颜色)
    • 更改TextField的背景颜色
    • 如何正确的写TODO,FIXME
      1. 去掉和修改UISearchBar 默认的背景色(灰色)和TextField颜色。
        测试环境:Xcode7, iOS9.2;
        默认背景色:


        UISearchBar 默认背景色(灰色)
    • 如何取消或修改默认的灰色背景呢?一行代码可以搞定:
    // !备注:当添加scopeButtons时,以下方法无效
    for (UIView *view in self.searchBar.subviews) {
            if ([view isKindOfClass:NSClassFromString(@"UIView")] && view.subviews.count > 0) {
                [[view.subviews objectAtIndex:0] removeFromSuperview];
                break;
            }
    }
    //  添加以下代码, 将UISearchBar背景颜色更改为蓝色
    //  self.searchBar.layer.backgroundColor = [UIColor blueColor].CGColor;  
    

    完成后的效果如下图:


    UISearchBar 去掉背景色后的效果

    <a href="changeTextFieldBgColor">更改TextField的背景颜色</a>

    //第一种方法,设置背景图片, 下面的方法支持iOS5.0
      [self.searchBa setSearchFieldBackgroundImage:[UIImage imageNamed:@"image"]  forState:UIControlStateNormal];
    
      //第二种方法,获取SearchBar内部的TextField,更改其颜色,不用额外增加图片
        UITextField *textField = [self.searchBa valueForKey:@"_searchField"];
        textField.backgroundColor = [UIColor clearColor];
    

    <a name="rendering-pane"></a>The Rendering Preference Pane

    This is where I keep preferences relating to how I render and style the parsed markdown in the preview window.

    3. 取消导航返回键的title:

    [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];
    

    4. CocoaPods install CorePlot

    测试环境: Xcode7, Simulator, iPhone6
    虽然CorePlot的主页上没有显示如何用CocoaPods安装CorePlot, 但我们仍然可以用CocoaPods安装CorePlot

        pod 'CorePlot', '~> 2.0'
    

    在项目中导入CorePlot:

    #import <CorePlot/ios/CorePlot.h>
    

    5. 如何统计项目中代码的数量

     在终端中进入项目所在文件夹,输入以下命令即可得到代码总行数(包括注释的代码哦)
    
     find . -name "*.m" -or -name "*.h" | xargs grep -v "^$"| wc -l
    

    6. UITabBarController+UINavigaitonController配合使用时,各种情况下,如何设置tabBarItem.title和navigaitionController的title?😢 每次都好烦,这次一次性搞定

      //在TabBarController的实现文件中实现以下方法
    /**
     **  添加带有导航控制器的childViewController
     **
     **  @param viewController 将要添加的ViewController, 将为其增加导航控制器
     **  @param show           是否显示导航控制器顶部的title
     **  @param same           如果show=YES,导航控制器顶部的title是否与tabbarItem的title一致
     **  @param title          导航控制器的title
     **  @param barItemTitle   UITabBarItem的title
     **  @param image          UITabBarItem的image
     **  @param selectedImage  UITabbarItem的selectedImage
     **/
     - (void)addChildViewControlle:(nonnull UIViewController *)viewController showTitle:(BOOL)show same:(BOOL)same title:(nullable NSString *)title barItemTitle:(nonnull NSString *)barItemTitle image:(nonnull UIImage *)image selectedImage:(nonnull UIImage *)selectedImage{
        if (show && (title == nil || [title isEqualToString:@""])) {
            [NSException raise:@"TabBarController set excepition" format:@"The navigaitoncontroller's title cannot be nil because of you choosing show title"];
            return;
        }
        viewController.tabBarItem.image = image;
        viewController.tabBarItem.selectedImage = selectedImage;
        SDRootNavigationController *nav =[[SDRootNavigationController alloc] initWithRootViewController:viewController];
        if (show) {
            if (same) {
                viewController.title = barItemTitle;
            }else{
                viewController.title = title;
                nav.tabBarItem.title = barItemTitle; //如果同时设置两个title,必须先实现导航栏的title,再实现tabbar的title
            }
        }else{
            nav.tabBarItem.title = barItemTitle;
        }
        
        [self addChildViewController:nav];
    }
    
    效果图

    7. Xcode目录自动同步

    iOS开发都知道,当我们在Xcode中新建一个Group的时候,并没有在finder中建立同步的Directory,当我们在finder中查找文件的时候,确实是一个大的麻烦,那么有解决的办法吗?答案是YES!
    Synx
    A command-line tool that reorganizes your Xcode project folder to match your Xcode groups.

    Github主页详细介绍了用法,真的很强大。但是在实际使用过程中可能出现以下的问题:

     //当执行gem install synx命令时,可能出现以下的error
    ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.
    

    http://stackoverflow.com/questions/14607193/installing-gem-or-updating-rubygems-fails-with-permissions-error
    我的办法是使用root权限

    sudo -s  //获取root权限
    gem install synx //安装aynx,如果在root权限下进行此命令会报错
    error : You cannot run Synx as root.
    //切换回普通用户,执行同步命令
    synx test.xocdeproj
    //这样Xcode目录就会和Finder目录一致了
    

    感谢叶孤城叶大的提点。😊

    8. ARC下打印对象的引用计数

        id obj = [[NSObject alloc]init];
        NSLog(@"retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(obj)));
    //output : retain count = 2
    

    9. 如何更改TabBar上面的横线

      - (UIImage *)contentImageWithColor:(UIColor *)color rect:(CGRect)rect{
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef contenxt = UIGraphicsGetCurrentContext();
        CGContextSetFillColorWithColor(contenxt, color.CGColor);
        CGContextFillRect(contenxt, rect);
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    //设置阴影照片,也就是那条横线,就是那个高度为0.5的UIImageView
        [self.tabBar setShadowImage:[self contentImageWithColor:RGBCOLOR(247, 248, 247) rect:CGRectMake(0, 0, SCREEN_WIDTH, 0.5)]];
    //设置的时候,必须同时设置bacjgroudImage, 否则无效。
        [self.tabBar setBackgroundImage:[self contentImageWithColor:RGBCOLOR(247, 248, 247) rect:CGRectMake(0, 0, SCREEN_WIDTH, 49)]];
    

    10. Xcode添加代码块, 快捷开发, 再也不用重复的写Property了

    /** <#summary#> */
    @property (nonatomic,strong) <#type#> *<#name#>;
    
    
    真相1
    真相2

    11. delloc中应该写什么?

    (1). 如果当前界面有NSTimer, 当该界面出栈时,应该将定时器的取消和置空这样处理

        - (void)viewDidDisappear:(BOOL)animated{
             [super viewDidDisappear:animated];
             [_myTimer invalidate];
              _myTimer = nil;
          }
    

    而不是放在delloc中,否则内存得不到释放
    (2). ARC中dealloc中不得显式调用[super dealloc]
    (3). [NSNotificationCenter defaultCenter] removeObserver 操作应该放在delloc中,而不是ViewDisapper中

    //官网解释
    The following example illustrates how to unregister someObserver for all notifications for which it had previously registered. This is safe to do in the dealloc method, but should not otherwise be used—use removeObserver:name:object: instead.
    

    12. 如何获取APP的名称?

    //获取appName-info.plist中app的名称(适用于只有一个名字的情况)
    [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]
    //获取InfoPlist.strings中的app名称(适用于有中英文或者多个Target的情况)
    [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"]
    

    13. Mac显示和隐藏文件夹

    在终端(Terminal)输入如下命令,即可显示隐藏文件和文件夹

    defaults write com.apple.finder AppleShowAllFiles -boolean true ; killall Finder
    

    如需再次隐藏原本隐藏的文件和文件夹,可以输入如下命令

    defaults write com.apple.finder AppleShowAllFiles -boolean false ; killall Finder
    

    14. 消除‘performSelector may cause a leak because its selector is unkonwn'

    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
          [self performSelector:selector withObject:info];
    #pragma clang diagnostic pop
    

    15: 获取设备内所有已安装APP的信息(访问私有方法,上架可能被拒)

        Class c =NSClassFromString(@"LSApplicationWorkspace");
        id s = [(id)c performSelector:NSSelectorFromString(@"defaultWorkspace")];
        NSArray *array = [s performSelector:NSSelectorFromString(@"allInstalledApplications")];
        for (id item in array){
            NSLog(@"%@",[item performSelector:NSSelectorFromString(@"applicationIdentifier")]);
            //NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleIdentifier")]);
            NSLog(@"%@",[item performSelector:NSSelectorFromString(@"bundleVersion")]);
            NSLog(@"%@",[item performSelector:NSSelectorFromString(@"shortVersionString")]);
        }
        
    
    

    16:获取系统版本号的正确方式

       [NSProcessInfo processInfo].operatingSystemVersion
        NSInteger major = [NSProcessInfo processInfo].operatingSystemVersion.majorVersion;
        NSInteger minor = [NSProcessInfo processInfo].operatingSystemVersion.minorVersion;
        NSInteger patch = [NSProcessInfo processInfo].operatingSystemVersion.patchVersion;
    

    17:一个全局的数组

    static NSString const *presendientOfUsa[4] = {
        @"Obama",
        @"Trump",
        @"Bush",
        @"Washington"
    };
    static NSString const *imgArr[3] = {
        @"引导页1",
        @"引导页2",
        @"引导页3"
    };
    除了NSString类型之外,都不允许在方法外部声明一个‘静态全局常量类型的OC对象’。
    你声明的static const NSArray * presendientOfUsa 在‘编译’的时候系统并不知道imgArr是什么类型,PS:全局常量类型的常量,static const是系统在编译的时候就需要确定你所定义的常量是什么类型的,然而OC的对象的类型是在‘运行时’确定的。与基本数据类型的确定时间不同,由编译的时候推到了运行时(OC支持多态的原因)。
    但是NSString除外,NSString是一种特殊的数据类型,有特殊的存储结构和权限来保证系统能够识别。
    

    18: 如何正确的写TODO,FIXME

    开发中有一些工作是需要我们稍后完成的,我们用TODO标记;有一些暂时处理不了的bug,用FIXME标记,后续处理,一般是这样


    TODO,FIXME

    有一个潜在的问题是:如果我们忘了?或者同事不知道这些标记,可能会出现遗留问题。我们希望在程序运行的时候,能够清除的看到,一般在Issue navigator上。
    那我们增加一个脚本,在程序运行时,自动检测出这些信息,并增加在Issue navigator上

    TAGS="TODO:|FIXME:"
    echo "searching ${SRCROOT} for ${TAGS}"
    find "${SRCROOT}" \( -name "*.m" \) -print0 | xargs -0 egrep --with-filename --line-number --only-matching "($TAGS).*\$" | perl -p -e "s/($TAGS)/ warning: \$1/"
    
    添加过程 运行后的效果

    19: Weak and Strong

    #define WeakSelf(type) __weak typeof(type) weak##type = type; //weak
    #define StrongSelf(type) __strong typeof(type) type = weak##type; //strong
    

    相关文章

      网友评论

        本文标题:iOS开发小技巧

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