iOS开发(小小总结-)

1.1 UINavigationController

导航栏控制器基本是项目必备啊,所以我们UI大姐们也是想着花样搞这个东西。我们做这方面开发的都是到NVC(码字 有点烦,后面都这样简称了),基本构造做开发的都是知道,是一个容器类 下面的VCs都是放在 stack中的。所以说,在stack里面那么多VC都是公用一个navigationBar啊。UI大姐就喜欢一个VC 拥有一个不同的bar....欲哭无泪。

现在按按修改程度,一点一点写。

1.1.1bar 上的返回按钮太丑了 

~~第一种方法就是原本backItem不动,将文字移到看不见的地方,并且更换返回图片。个人感觉不是很好

~第二个方法就是整个替换掉leftItem,当然随之而来的问题就是要实现点击返回功能和左滑返回功能。

因为要实现左滑 最好还是重写一个NVC子类 而不是用appearce

//遵循手势的协议@interfaceIGONavigationController()- (void)viewDidLoad{    [superviewDidLoad];self.interactivePopGestureRecognizer.delegate=self;}//替换掉各个页面的返回按钮- (void)pushViewController:(UIViewController*)viewController animated:(BOOL)animated{//设置返回按钮viewController.navigationItem.leftBarButtonItem= [[UIBarButtonItemalloc] initWithImage:[UIImageimageNamed:@"fanhui"] style:UIBarButtonItemStyleDonetarget:selfaction:@selector(popViewControllerAnimated:)];    [superpushViewController:viewController animated:animated];}//右滑返回的处理- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer{BOOLok =YES;// 默认为支持右滑反回if([self.topViewControllerisKindOfClass:[RootViewController class]] ||        [self.topViewControllerisKindOfClass:[Root1ViewController class]] ||        [self.topViewControllerisKindOfClass:[Root2ViewController class]] ||        [self.topViewControllerisKindOfClass:[Root3ViewController class]]) {returnNO;    }returnok;}

要注意的是 开起左滑 返回 移动去去掉 NVC 的rootVC 不然就会出现空stack的问题,从而导致各种问题。

1.1.2bar  有的页面需要,有的页面不需要

这个也是挺烦的,我看到很多同鞋。在处理这个问题上,都会这么写。加入A页面需要,B页面不需要的话

A- (void)viewWillAppear:(BOOL)animated {self.navigationController.navigationBar.hidden=NO;}B- (void)viewWillAppear:(BOOL)animated {self.navigationController.navigationBar.hidden=YES;}- (void)viewWillDisappear:(BOOL)animated {self.navigationController.navigationBar.hidden=YES;}

这种做法,也就效果勉强出来了,不过会带来一系列的问题

·····1 左滑 返回的时候NVC 无法分清那个VC 有Bar .出现显示问题

·····2当2个VC对应 statusBar 的字体颜色不一样的时候。上面这种做法,虽然隐藏了Bar 但在VC中重写preferredStatusBarStyle依旧没有作用的。NVC很难分清其中的界限。

正确的做法应该是

这种修改Bar 的工作还得交给代理去做,毕竟出现的意外情况,苹果的大牛们都考虑到了,代码要写在改写的地方。

因为我子类化得NVC用的地方很多,所以对于Bar的代理 我基本会放在rootVC中

下面的代码 就是在 SearchViewController和SearchResultController中隐藏了Bar

在ProductDetailViewController中对Bar的样式 进行了修改。

//在rootVC 中 遵循NVC代理 UINavigationControllerDelegate//隐藏导航栏- (void)navigationController:(UINavigationController*)navigationController willShowViewController:(UIViewController*)viewController animated:(BOOL)animated{// 隐藏BarBOOLisShowHomePage = [viewController isKindOfClass:[SearchViewController class]] || [viewController isKindOfClass:[SearchResultController class]];    [self.navigationControllersetNavigationBarHidden:isShowHomePage animated:YES];UIImage*shadowImage =self.navigationController.navigationBar.shadowImage;UINavigationBar*bar =self.navigationController.navigationBar;if([viewController isKindOfClass:[ProductDetailViewController class]]) {        bar.shadowImage= [UIImagenew];        [bar lt_setBackgroundColor:[UIColorclearColor]];    }else{        bar.shadowImage= shadowImage;        [bar setBackgroundImage:[UIImageimageNamed:@"导航栏"] forBarMetrics:UIBarMetricsDefault];    }}

这样 在左滑的时候消除了显示问题,以及在在隐藏了Bar的VC中无法控制statusBar的状态颜色问题。

1.1.3 每个bar完全不同

童鞋 全隐藏 自定义吧QAQ

1.2UINavigationBar

大家现在都是最低支持7以上了,太老的东西就不涉及了。

bar 有2个烦人的地方就是偏移量和透明度了

1.2.1偏移量

我们知道默认translucent = YES。就是Bar 是有透明度的。

在有透明度的情况下,系统默认automaticallyAdjustsScrollViewInsets属性是YES就是对于scrollerview的子类会默认content偏移64个单位。这样做的目的,既然Bar都是透明的了,系统就觉得你的scrollerView一定在会在(0,0)点,content偏移一个64个单位。在你滑动的时候,隐藏在Bar下面的Content会有一个模糊显示的效果。QAQ

如果你不想要这个偏移量

1 设置translucent = NO,既然Bar不透明。自然不需要偏移量喽

2 关闭这个偏移量,automaticallyAdjustsScrollViewInsets = NO

提一下像tableView,在storyboard 设置上下左右的约束。结果cell上面多了一块空白。就是这个问题。

1.2.2透明度

这种需求现在太多了,尤其都要做成淘宝那样的详情页,烦的一腿。现在我就在分析一下。

首先如果想滑动控制Bar的透明度,translucent 属性一定要设置成YES(默认)

当Bar 被设置成透明状态的时候

ED5A2936-7199-47B4-9E14-73E44F49BE74.png

还是这张图 _UIBackdropView 这个view是设置半透明毛玻璃效果的view(当然只在透明属性为YES 或者 没有背景图片的时候才会出现)

首先我们要去掉层特殊的视觉图层 利用设置BarBackground图片

- (void)setBackgroundImage:(nullableUIImage*)backgroundImage forBarMetrics:(UIBarMetrics)barMetricsNS_AVAILABLE_IOS(5_0)UI_APPEARANCE_SELECTOR;

千万不要用translucent = NO 这种方法来去掉视觉图层,都设置不透明了,那我们还玩按什么是吧。。。

这里注意的是我们设置的barTintColor 以及 background 都是对_UINavigationBarground这个Imageview来进行操作的。

这时候 我们就剩下Bar 和 BarBackground两层了

首先我们来说下Bar上面设置颜色的3个方法

//背景颜色 继承父类的 不过这个是设置bar 的背景颜色@property(nullable,nonatomic,copy)UIColor*backgroundColorUI_APPEARANCE_SELECTOR;// default is nil. Can be useful with the appearance proxy on custom UIView subclasses.//这个是设置bar 上面的那层 barBackground imaeView的颜色@property(nullable,nonatomic,strong)UIColor*barTintColorNS_AVAILABLE_IOS(7_0)UI_APPEARANCE_SELECTOR;// default is nil//这个是item的颜色@property(null_resettable,nonatomic,strong)UIColor*tintColor;

再来看下各个控件的高度 bar 本身是44 而barBackgoundImageView 确实64.。

这就是 为什么你设置了bar你颜色 或者 背景图片 。为什么status Bar 的背景也会跟着改变哦。

其实Bar 本身的颜色几乎很少设置,因为现在都要2个bar 一致才符合主流嘛

怎么改变barBackgroundImageView的背景颜色,又成了一个问题。因为刚才为了去掉视觉图层,我们给barBackgroundImageView 赋值了一个空图片。问题出来了,有了图片属性之后,给barBackgroundImageView设置背景颜色就没有用了,现在主流的做法是

查一个view进去  去调节这个 view的颜色 来控制bar 的背景颜色控制

写个类目 给 bar 加一个 - (void)iGo_setBackgroundColor:(UIColor *)backgroundColor

- (UIView*)backView{returnobjc_getAssociatedObject(self, &backView);}- (void)backView:(UIView*)backView{    objc_setAssociatedObject(self, &backView, backView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}- (void)iGo_setBackgroundColor:(UIColor*)backgroundColor{if(!self.backView) {        [selfsetBackgroundImage:[UIImagenew] forBarMetrics:UIBarMetricsDefault];self.backView= [[UIViewalloc] initWithFrame:CGRectMake(0, -20,CGRectGetWidth(self.bounds),CGRectGetHeight(self.bounds) +20)];            [selfinsertSubview:self.backViewatIndex:0];    }self.backView.backgroundColor= backgroundColor;}

最后 我们需要调节透明度的页面

在滑动过程中 调节颜色的透明度 就OK拉

- (void)scrollViewDidScroll:(UIScrollView*)scrollView{UIColor* color = [UIColorcolorWithHexString:@"#fa2245"];CGFloatoffsetY = scrollView.contentOffset.y;if(offsetY >50) {CGFloatalpha = MIN(1,1- ((50+64- offsetY) /64));        [self.navigationController.navigationBarlt_setBackgroundColor:[color colorWithAlphaComponent:alpha]];    }else{        [self.navigationController.navigationBarlt_setBackgroundColor:[color colorWithAlphaComponent:0]];    }}

2旋转处理

一半我我们的app不支持旋转的话 就会关掉下面这两个向选项

来禁止横屏。

但如果我们的app部分页面支持横屏,部分不支持的话就要做一些处理了

我们不需要对每一个VC都进行处理,只要对最外层的容器类VC重写一些方法。

例如我的所有VC都是由tabbar管理的

我会在tabbar的子类中

#pragma mark -- Orientation//如果目前是竖屏 则不支持旋转,如果现在是横屏 则支持旋转- (BOOL)shouldAutorotate{return!([UIApplicationsharedApplication].statusBarOrientation==UIInterfaceOrientationPortrait);}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{returnUIInterfaceOrientationPortrait;}- (UIInterfaceOrientationMask)supportedInterfaceOrientations {returnUIInterfaceOrientationMaskPortrait;}

在某些需要旋转的VC继续重写这几个方法

//因为是个别页面是横屏 其他页面都是竖屏,这里可以直接返回YES//如果有特殊情况 也可以判断返回#pragma mark -- orientation- (BOOL)shouldAutorotate {returnYES;}- (UIInterfaceOrientationMask)supportedInterfaceOrientations {returnUIInterfaceOrientationMaskLandscapeRight;}

这样即使是横屏状态打开app 也会自动切换成竖屏。不过如果你在tabbar 在加一些东西的话可能会出现问题。

中间这个 取 的按钮 ,按照系统的是无法实现的。又不想重新自定义tabbar。这时候我就在tabbar中中间加上一个Button.来模拟tabbar item 的功能。

这时候 从横屏 进来之后,就会出现问题,因为bar 上是无法添加约束的,所以只能用frame 布局。 但是横竖屏的宽高大小 是相反的0.0

这时候就需要判断了

//可以用宽高大小判断 也可以用上面的设备方向判断CGFloatwidth = kScreenHeight>kScreenWidth? kScreenWidth: kScreenHeight;UIButton*getGoodsButton = [[UIButtonalloc] initWithFrame:CGRectMake(width/2- kButtonWidth/2,0, kButtonWidth, kButtonHeight)];

这只是一盒小例子,总之 处理屏幕旋转的时候要注意布局。尤其是没有约束控制的布局

3扫描

3.1淘宝的扫描效果

这个看起来很炫酷,其实就是一个网格的图片上下移动,把多余的部分Mask 掉就可以了。

//放个可视面积差不多大小的view,将imageview 加上去UIView*tempView = [[UIViewalloc] initWithFrame:VISIBLERECT];//重点tempView.layer.masksToBounds=YES;    [self.viewaddSubview:tempView];    _scanningImageView = [[UIImageViewalloc] init];    [tempView addSubview:_scanningImageView];    _scanningImageView.image= [UIImageimageNamed:@"扫描网格"];

上下的移动的代码就不贴,思路知道了。做起来很简单

3.2 unsupported type found

在设置AVCaptureMetadataOutput的metadataObjectTypes时候,一定要注意设置在载入session 之后不然就会出现 特别迷惑人的错误

E9F4D45F-0FA8-426D-AA5C-11A7FEB11253.png

我纳闷了好久 啊 。。。。。要记得 前后 顺序

[_session addInput:_input];    [_session addOutput:_output];    _output.metadataObjectTypes= @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];

3.3 坐标转换

我们知道扫描的可视范围rectOfInterest坐标系统 和 我们 UIKit用的坐标系统不一样,我们在设置这个坐标的时候有两种做法

1,根据 两种坐标系 自己换算去 其实就是将屏幕左翻转 (x,y轴对调)

CGRectMake(y的起点/屏幕的高,x的起点/屏幕的宽,扫描的区域的高/屏幕的高,扫描的区域的宽/屏幕的宽)

2,通过系统的方法换算

在通过系统的方法换算的时候,出现了小问题

-(CGRect)metadataOutputRectOfInterestForRect:(CGRect)rectInLayerCoordinatesNS_AVAILABLE_IOS(7_0);

在使用这个方法换算的时候始终是没有作用的,

其实方法是没错,但是调用的时机很重要

当我们收到AVCaptureInputPortFormatDescriptionDidChangeNotification通知的时候在进行左边转换就没有问题了

具体原因,我也没有找到。希望大神指点

[[NSNotificationCenterdefaultCenter] addObserverForName:AVCaptureInputPortFormatDescriptionDidChangeNotificationobject:nilqueue:[NSOperationQueuecurrentQueue] usingBlock:^(NSNotification* _Nonnull note) {        _output.rectOfInterest= [_scanView metadataOutputRectOfInterestForRect:VISIBLERECT];    }];

4UIButton

我们都知道button中有2个子控件 一个imageView 一个label。默认imageview 在左label 在右。我们控制好这几个控件 能满足好多需求

首先 button 是UIControl的子类

UIControl有控制content位置的属性

typedefNS_ENUM(NSInteger,UIControlContentVerticalAlignment) {UIControlContentVerticalAlignmentCenter=0,UIControlContentVerticalAlignmentTop=1,UIControlContentVerticalAlignmentBottom=2,UIControlContentVerticalAlignmentFill=3,};typedefNS_ENUM(NSInteger,UIControlContentHorizontalAlignment) {UIControlContentHorizontalAlignmentCenter=0,UIControlContentHorizontalAlignmentLeft=1,UIControlContentHorizontalAlignmentRight=2,UIControlContentHorizontalAlignmentFill=3,};@property(nonatomic)UIControlContentVerticalAlignmentcontentVerticalAlignment;// how to position content vertically inside control. default is center@property(nonatomic)UIControlContentHorizontalAlignmentcontentHorizontalAlignment;// how to position content hozontally inside control. default is center

只要我们合理的运用 content(imageview 和 label) 可以在button 内部的16个位置上。

但有时这个东西满足不了我们的需求

看个例子

FE0CDCAA-451F-4ACF-97BA-74694BA7548B.png

这种图片在右边 文字在左边,就令我们很蛋疼。看到这个需求有的童鞋可能就会自定义一个视图类了,其实不需要button的属性就可以帮助我们解决

@property(nonatomic)UIEdgeInsetscontentEdgeInsetsUI_APPEARANCE_SELECTOR;// default is UIEdgeInsetsZero@property(nonatomic)UIEdgeInsetstitleEdgeInsets;// default is UIEdgeInsetsZero

可以设置图片文字的偏移量,不过此处有坑

#import"UIButton+Common.h"@implementationUIButton(Common)- (void)reverseImageAndTitle {CGRectimageFrame =self.imageView.frame;CGRecttitleFrame =self.titleLabel.frame;self.titleEdgeInsets=UIEdgeInsetsMake(0, -imageFrame.size.width*2,0,0);self.imageEdgeInsets=UIEdgeInsetsMake(0,0,0, -titleFrame.size.width*2);}@end

这边单位是px 不是pt 整个人都蒙了有木有。

不过还好发现了

5UITextField

C04C5E25-F123-4372-A707-B14ACD5D7EAD.png

设置左边图片 sb 上面没有对应的属性。。。庆幸的在textfield中还是有对应的属性 不过切图的时候记得要来拿左边的空白一起切下来

@property(nullable,nonatomic,strong)UIView*leftView;// e.g. magnifying glass@property(nonatomic)UITextFieldViewModeleftViewMode;// sets when the left view shows up. default is UITextFieldViewModeNever

6.tableView collectionView

1.圆角 始终是个争论的话题了。

各种花式的解决办法。

其实我认为,如果固定的页面 如果只有个别原角,无需优化

如果想tableview 这样大量重复的圆角,其实只要做设置一次缓存即可。开启光栅化,可解决性能问题。

什么 离屏渲染 CPU GPU线程切换消耗大量性能,我只做一次还不行meQAQ

//rasterizecell.layer.shouldRasterize=YES;    cell.layer.rasterizationScale= [UIScreenmainScreen].scale;

不要各种贝塞尔 各种mask 简单点好。

2.对于selected

tableview 和 collectionview 都是支持单选的,只要重写  selected方法就行,系统在你创建cell类的时候也预留了这个方法。

不过要选择默认的selected 设置cell.seleted 是不行的

//collectionView- (void)selectItemAtIndexPath:(nullableNSIndexPath*)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;

seleted 可以完美的实现默认选中 单选的效果。

对于对选 智能自定义了

3section 展开

只要用数组记录每个section 需要展示的cell 的数量 刷新view 就可以了

7VC设置背景图片

没有必要再放在一个imageview上面 直接在VC的view.layer上画就可以了

self.view.layer.contents= (__bridgeid_Nullable)([UIImageimageNamed:@"beijing"].CGImage.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容