项目中遇到的问题

哇咔咔,终于开始了自己的项目,嘿嘿,现在把做项目过程中遇到的问题和一些技巧记下来。

—————————–

appicon问题

一开始遇到了appicon的问题,唉,连@2x和@3x都不知道是啥意思。然后往上面放图片的时候就一直报错。


就是上面这个,首先要知道@2x就是扩大2倍,@3x就是扩大3倍。然后扩大谁的倍数呢,就是下面那个40pt,所以你在相应位置放图标时要保证大小跟要求的一样,还有就是命名方式,在图片名称后面加上其放大倍数,比如”imageName@2x”。嗯,就是酱紫。

然后遇到了pch的问题,我用的是Xcode7,自从Xcode6开始苹果就不在新建项目的时候自动创建.pch文件了。于是乎,我就自己创建呗,然后我笨笨的,连这一步也出现了问题,自己翻的时候愣是没看见,其实就在iOS->other里面的PCH文件。

项目中遇到的问题_第1张图片

然后创建完了,我就写预定义的一些东西。然后嘞,发现并不能用。。。我就搜一搜,这是咋的了。因为我得设置一些东西

把Precompile Prefix Header右边的NO改为Yes,然后在Precompile Prefix Header下边的Prefix Header右边双击,添加刚刚创建的pch文件的工程路径,添加格式:“$(SRCROOT)/项目名称/pch文件名” ,$(SRCROOT)的意思就是工程根目录的意思,后面那个pch文件名要加上.pch后缀。

然后就可以使用在pch中预定义的东西了。

—————————–

精简代码问题

下面说说精简代码的问题。一般当我们写一段代码发现重复性太多的时候,就要考虑一下重构了。就是把变化的地方变成参数,不变的地方抽到一个函数中。

—————————–

tabbar图片位置问题

虽然遇到问题的时候烦恼的不行,但是,解决的就有新的收获,超开心哈哈,虽然,现在还什么都没做出来呢。

在设置tabbarItem的图片的时候遇到了一些问题。

iOS7之后image出现了新的功能,就是渲染图片,暂时这样说。有下面三种枚举类型,效果如下图。

UIImageRenderingModeAutomatic,  
UIImageRenderingModeAlwaysOriginal,     
UIImageRenderingModeAlwaysTemplate

项目中遇到的问题_第2张图片

这个就看你自己想要的效果了,我想要original那种的,就是按我自己配的图来,不用你渲染。

这个我又遇到了一个小问题,就是我发现我选择的时候是按我设置好的选择的图片来的,但是,不选择的时候被渲染成灰色的了。。。这是怎么回事,我百思不得姐啊。后来,我才发现,我太马虎了,一个是默认的图片,另一个是选中图片,我只向选中图片发送imageWithRenderingMode:消息了,默认的忘记发送了,怪不得错了,活该。。

接着再运行还有问题,就是整个图片向上飘,就是下面这个样子

项目中遇到的问题_第3张图片

设置一下inset属性就可以,如下操作:

UIEdgeInsets insets = UIEdgeInsetsMake(6, 0, -6, 0);//至于为什么是6我还不太清楚,先放着
childVc.tabBarItem.imageInsets = insets;

然后这块就暂时没有问题了,哈哈。

—————————–

隐藏tabbar问题

在用tabbarcontroller时,在其中一个界面点击跳转到另一个界面时,会发现底下的tabbar还在,这可能不是我们想要的效果,不过没关系,设置一下就好。
当你要跳转到另一个视图控制器的时候,你肯定要创建一个对吧,然后设置他的hidesBottomBarWhenPushed属性为YES就可以了。

即酱紫:

UIViewcontroller *vc = [[UIViewcontroller alloc] init]; vc.hidesBottomBarWhenPushed = YES;

搞定。

—————————–

控件显示问题

当你发现一个控件显示不出来的时候,有可能时内容有问题,或者是忘记设置尺寸了。尤其是自定义的东西,一定要设置尺寸。
还有一点需要注意就是不能给控件的size赋值,因为UIView(控件都是继承自UIView),要么就在初始化的时候吧size设置好,要不就设置frame。所以这样会造成一些不必要的麻烦,这个时候category就有用处了,为UIView写一个分类,添加上相应的属性,然后完成setter和getter方法就可以了。

举个例子:

- (void)setY:(CGFloat)y {
    CGRect frame = self.frame;
    frame.origin.y = y;
    self.frame = frame;
}

—————————–

定制按钮

因为想要定制导航控制器上的导航按钮,所以自定义一个导航控制器,然后重写pushViewController: animated:这个方法,即拦截该方法,记得要在里面调用一下父类的这个方法。然后就可以做一些我想要的操作了,比如我想定制它的导航按钮,然后我蠢蠢的去设置navigationController的navigationItem属性(即self.navigationItem)。对于这个行为我有一下感想。

我又犯蠢了,犯蠢了,蠢死了。对于navigationController的navigationItem属性是只读的!亲!睁大眼睛看清楚,看属性的时候把参数也看清楚了好吗!!!

嗯,所以在这个方法里面这样设置就可以了viewController.navigationItem.leftBarButtonItem。
这个也涉及到经验问题,有的人一下就发现,我们一般不都是在viewController里面设置这个属性吗。嗯,经验很重要。

然后你可以在注意一点,就是你可能定制的是返回按钮,如果这样的话,第一次push的界面并不需要放上返回箭头。所以你可以在上面的方法里面判断一下。

self.viewControllers.count > 1 // 如果该导航控制器里面的自控制器大于1的时候才需要返回上一个界面,这里也要注意,这个判断应该放在调用父类的该方法下面,至于为什么,自己思考一下

后期,如果你某个子控制器不想用这个定制的item,那么你可以进行覆盖。怎么覆盖呢,首先我们要知道它是先执行push操作,然后再执行每个子控制器的viewDidLoad方法

—————————–

duplicate 编译错误

当编译遇到 duplicate symbol _OBJC_METACLASS…..错误时,一般情况下就是导入了.m 文件。
或者就是项目中有两个一样的.m文件。

—————————–

封装代码

当遇到一大段一大段重复的代码的时候,比如,你有很多导航控制器,你想要给它设置barbuttonItem,那么你就会写很多这样重复的代码,因为他还有left和right。这个时候就要想到封装,而且为了提高易读性,就用category进行封装,对哪个对象进行封装就给哪个对象添加分类和类方法,这就就是所谓工厂模式,把一个东西的创建封装起来,只调用接口就好了,不用管工厂中是如何创建的,这个时候就要好好考虑一下参数的设置问题。要注意命名格式,最好遵守[NSString stringwith…]这种格式。

—————————–

关于字体属性问题。

之前蠢蠢的以为如果要更改文字的颜色只能通过绘制的方法,蠢死了。新技能get。

UIBarButtonItem *item = [UIBarButtonItem appearance];
    // key : NS***AttributeName
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = XGJColor(253, 132, 171, 1.0);
textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:16];
[item setTitleTextAttributes:textAttrs forState:UIControlStateNormal];

嗯,就酱紫就搞定了。

—————————–

调试技巧

开发中我们经常要打印日志,就会写很多NSLog。。。但是发布的时候要注释掉这些打印,否则会耗性能。难道要一个一个写一个一个主食。没那么傻,get新技能吧。
在pch文件中写入下面的代码就搞定了。

#ifdef DEBUG

#define XGJLog(...) NSLog(__VA_ARGS__) // 处于开发阶段
#else
#define XGJLog(...) // 处于发布阶段
#endif

—————————–

关于SearchBar

在写这个SearchBar的时候,会有很多限制。比如你放进去一个图片,太大了,你想设置一个宽高,就设置不了。所以,用Textfield来写,怎么写呢,textfield长得不是就很像搜索框吗。然后他有一个leftview属性,设置leftview的同时也要设置一下leftViewMode,因为如果不设置他默认是UITextFieldViewModeNever,也就是永远不显示。

代码如下:

UITextField *searchBar = [[UITextField alloc] init];
searchBar.width = 520;
searchBar.height = 40;
searchBar.background = [UIImage imageNamed:@"searchbar_textfield_icon"];

UIImageView *searchIcon = [[UIImageView alloc] init];
searchIcon.image = [UIImage imageNamed:@"search_icon"];
searchIcon.width = 26;
searchIcon.height = 26;
searchIcon.contentMode = UIViewContentModeCenter; // 这里设置图片为居中效果
searchBar.leftView = searchIcon;
searchBar.leftViewMode = UITextFieldViewModeAlways;
self.navigationItem.titleView = searchBar;

关于那个textfield的图片,可以进行拉伸,这个选中图片后在工具栏中Attributes Inspector里面的最下面,有个Slicing,把SLice设置为Horizontal and Vertical ,然后Center 为Stretches就行了,其他属性他是自己自动设置的。这里的话,还不是很清楚这是为什么,但是如果你不这么操作,会很丑。因为我找不到那种宽度的搜索框,是由一个正方形进行拉伸的。

—————————–

创建ImageView的小细节

以下两个创建ImageView对象的方法是有区别的,注意一下。不仅仅是UIImageView,还有其他的控件也有这样的问题,因此要记住这个地方,以后出现问题知道是怎么回事。

UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; // 这种方法会将imageVIew的宽高设置为图片的宽高
UIImageView *imageView = [[UIImageView alloc] init]; // 这种方式创建完是没有宽高的,除非你屌用initWithFrame初始化他的宽高 

—————————–

—————————–

—————————–

—————————–

—————————–

—————————–

—————————–

你可能感兴趣的:(项目中遇到的问题)