其他小技巧看這裡:iOS 開發的9個超有用小技巧
很久沒寫博客了,最近一堆破事和工作上的事,導致博客斷更一陣子了,這篇博客既是一些技巧篇也是一些我在最近的日常的開發中使用到的技巧和筆記的記錄。 (ps:希望大家不要像我一樣,事情一忙就忘了做筆記)。
1.神器計算圖片位置的函數:AVMakeRectWithAspectRatioInsideRect()
通過這個函數,我們可以計算一個圖片放在另一個 view 按照一定的比例居中顯示,可能說的我比較抽象,還是用圖來顯示,可以說它可以直接一個 image 以任何的比例顯示顯示在 imageview 中居中所處的位置,拿 UIViewContontAspectFit來演示,
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 300, 300)]; imageView.center = self.view.center; imageView.backgroundColor = [UIColor redColor]; imageView.contentMode = UIViewContentModeScaleAspectFit; UIImage *image = [UIImage imageNamed:@"mm.jpg"]; imageView.image = image; CGRect iamgeAspectRect = AVMakeRectWithAspectRatioInsideRect(image.size, imageView.bounds); NSLog(@"iamgeAspectRect = %@, imageView =%@",NSStringFromCGRect(iamgeAspectRect),NSStringFromCGRect(imageView.frame)); [self.view addSubview:imageView];
圖片顯示如下:(ps:這妹子是我公司一個管理公司weibo賬號的妹紙,目前我在勾搭,你們不要羨慕,生活依然很美好的嘛!)
log 打因結果如下:
iamgeAspectRect = {{37.563884156729145, 0}, {224.87223168654171, 300}}, imageView ={{37.5, 183.5}, {300, 300}}
可以從 log 得出 對應的 image 以 aspectFit 的方式在 imageView 的位置,在 imageView 中的位置是(37.5,0)。這樣你根本不需要任何多的代碼來計算了。(ps:這個函數是在 AV框架的,童鞋們自行導入。)
具體它的其他的好處,如果你是做相機或者圖片處理的你就知道它的好處了,什麼處理橫屏照片了,16:9,1:1,4:3圖片在控件中的位置,控件上的點對應圖片上的點的位置拉,等等。
2.關於 如果一個矩形如果做了平移旋轉縮放等一系列操作之後,上下左右的四個點(甚至矩形上任意一個點)的位置。
CGPoint originalCenter = CGPointApplyAffineTransform(_mStyleLeftEyeView.center, CGAffineTransformInvert(_mStyleLeftEyeView.transform)); //1左眼內眼角 CGPoint bottomRight = originalCenter; bottomRight.x += _mStyleLeftEyeView.bounds.size.width / 2; bottomRight.y += _mStyleLeftEyeView.bounds.size.height / 2; bottomRight = CGPointApplyAffineTransform(bottomRight, _mStyleLeftEyeView.transform);
首先這個 styleLeftView 就是一個矩形的 view,這裡以右下角的點做示范,做無論做了任何的 tranform 之後都可以得到它的點的位置,具體它用在什麼位置,我就不方便透露了,(媽蛋,說多了,就相當於把公司我寫的代碼開源了)
3.在使用 pinch 的時候我們設置 pinch 縮放的最大值和最小值(系統默認沒有提供最大值和最小值的 api),設置 pinch的 maxValue,minValue.
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) { // Reset the last scale, necessary if there are multiple objects with different scales mLastScale = [gestureRecognizer scale]; } if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { CGFloat currentScale = gestureRecognizer.view.transform.a; //計算出 縮放平移的 scale CGFloat deletaScale = (mLastScale - [gestureRecognizer scale]); CGFloat newScale = 1 - deletaScale; newScale = MIN(newScale, kMaxScale / currentScale); newScale = MAX(newScale, kMinScale / currentScale); CGAffineTransform scaleTransform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale); //隨著移動要調整一下 view 的 center point 位置 [gestureRecognizer view].transform = scaleTransform; NSLog(@"self.iconView.height = %@ ,width = %@",@(self.iconView.width),@(self.iconView.height)); mLastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
聰明的小伙伴應該一下就知道這個是怎麼處理的,唯一需要注意的是 當前的縮放的 scale,最初查的資料是通過
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
來得到的,但是不知道為什麼 layer的 transform 的 scale 和 view 的當前的縮放 scale 不一致,我通過 debug,得到 view的 transform 的 a的值和當前的縮放值是一樣的,因為工作緣故不能凡事挖的特別透,所以大家想知道為什麼 a 就是 scale 值可以自行查閱分享給我。
4.最後再分享給大家一個縮放時,縮放的中心點的問題,絕大部分我們縮放都是以 view 的中心點來縮放的,但是某些情況下我們需要以下面的邊不動。譬如下面圖像這種
這種方式,我最早是希望通過縮放的時候同時平移就可以處理了,根據縮放的尺寸,縮放到上面多少就平移下來多少,保持下邊不動,但是發現特別麻煩。後來使用 layer 的 anchorPoint 來出來,發現特別簡單,唯一需要填的坑就是改變 anchorPoint 的時候,它的 frame 會發生瞬移的變化,天啊噜,還好我完美解決!
-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view { CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x, view.bounds.size.height * anchorPoint.y); CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x, view.bounds.size.height * view.layer.anchorPoint.y); newPoint = CGPointApplyAffineTransform(newPoint, view.transform); oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform); CGPoint position = view.layer.position; position.x -= oldPoint.x; position.x += newPoint.x; position.y -= oldPoint.y; position.y += newPoint.y; view.layer.position = position; view.layer.anchorPoint = anchorPoint; }
通過這種方式設置 anchorPoint,如果後續你做平移前 速度把 AnchorPoint設置到(0.5,0.5)的位置,就沒有問題了。
5.最後一個就是分享下大家團隊如果使用 git 來開發,可以快速定位你現在看不懂的代碼是哪個2貨寫的,然後即使把鍋甩到他身上(ps:如果是自己寫的,你就默不作聲,別讓別人知道這個技巧哈),其實就是 show blame for line.
當然這種操作是可以使用快捷操作的,熟悉我的人應該都知道我的風格,我把 show blame for line 改成快捷鍵?+c 的操作了(ps:怎麼改看我前面的博客)。好了以後有問題及時找到你的同事,質問他你這寫的什麼垃圾代碼,我這種大神都不看不懂。
結束語
原來沒有用 swift 寫演示,最近也是在學,但是沒有時間寫,本來要寫的 storyBoard和 AutoLayout 技巧篇,也是因為最近人寫這個太多的,感覺有不少雷同,但是只寫出來不同的也寫不出來太多,原釀我(後續我會學著寫動畫,到時給你們帶來酷炫的動畫哦)!