一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - IOS - iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法

iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法

2020-12-24 15:26一片楓葉 IOS

這篇文章主要介紹了iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法,包括Transform變化矩陣原理的講解,需要的朋友可以參考下

加速計(jì)是整個(gè)ios屏幕旋轉(zhuǎn)的基礎(chǔ),依賴加速計(jì),設(shè)備才可以判斷出當(dāng)前的設(shè)備方向,ios系統(tǒng)共定義了以下七種設(shè)備方向:
 

復(fù)制代碼 代碼如下:


typedef ns_enum(nsinteger, uideviceorientation) {

 

    uideviceorientationunknown,

    uideviceorientationportrait,            // device oriented vertically, home button on the bottom

    uideviceorientationportraitupsidedown,  // device oriented vertically, home button on the top

    uideviceorientationlandscapeleft,       // device oriented horizontally, home button on the right

    uideviceorientationlandscaperight,      // device oriented horizontally, home button on the left

    uideviceorientationfaceup,              // device oriented flat, face up

    uideviceorientationfacedown             // device oriented flat, face down

};


 
   以及如下四種界面方向:
 

復(fù)制代碼 代碼如下:


typedef ns_enum(nsinteger, uiinterfaceorientation) {

 

    uiinterfaceorientationportrait           = uideviceorientationportrait,

    uiinterfaceorientationportraitupsidedown = uideviceorientationportraitupsidedown,

    uiinterfaceorientationlandscapeleft      = uideviceorientationlandscaperight,

    uiinterfaceorientationlandscaperight     = uideviceorientationlandscapeleft

};

 

 
 
一、uikit處理屏幕旋轉(zhuǎn)的流程 
 
  當(dāng)加速計(jì)檢測(cè)到方向變化的時(shí)候,會(huì)發(fā)出 uideviceorientationdidchangenotification 通知,這樣任何關(guān)心方向變化的view都可以通過注冊(cè)該通知,在設(shè)備方向變化的時(shí)候做出相應(yīng)的響應(yīng)。上一篇博客中,我們已經(jīng)提到了在屏幕旋轉(zhuǎn)的時(shí)候,uikit幫助我們做了很多事情,方便我們完成屏幕旋轉(zhuǎn)。
 
  uikit的相應(yīng)屏幕旋轉(zhuǎn)的流程如下:
 
1、設(shè)備旋轉(zhuǎn)的時(shí)候,uikit接收到旋轉(zhuǎn)事件。
 
2、uikit通過appdelegate通知當(dāng)前程序的window。
 
3、window會(huì)知會(huì)它的rootviewcontroller,判斷該view controller所支持的旋轉(zhuǎn)方向,完成旋轉(zhuǎn)。
 
4、如果存在彈出的view controller的話,系統(tǒng)則會(huì)根據(jù)彈出的view controller,來判斷是否要進(jìn)行旋轉(zhuǎn)。
 
 
 
二、uiviewcontroller實(shí)現(xiàn)屏幕旋轉(zhuǎn)
 
  在響應(yīng)設(shè)備旋轉(zhuǎn)時(shí),我們可以通過uiviewcontroller的方法實(shí)現(xiàn)更細(xì)粒度的控制,當(dāng)view controller接收到window傳來的方向變化的時(shí)候,流程如下:
 
1、首先判斷當(dāng)前viewcontroller是否支持旋轉(zhuǎn)到目標(biāo)方向,如果支持的話進(jìn)入流程2,否則此次旋轉(zhuǎn)流程直接結(jié)束。
 
2、調(diào)用 willrotatetointerfaceorientation:duration: 方法,通知view controller將要旋轉(zhuǎn)到目標(biāo)方向。如果該viewcontroller是一個(gè)container view controller的話,它會(huì)繼續(xù)調(diào)用其content view controller的該方法。這個(gè)時(shí)候我們也可以暫時(shí)將一些view隱藏掉,等旋轉(zhuǎn)結(jié)束以后在現(xiàn)實(shí)出來。
 
3、window調(diào)整顯示的view controller的bounds,由于view controller的bounds發(fā)生變化,將會(huì)觸發(fā) viewwilllayoutsubviews 方法。這個(gè)時(shí)候self.interfaceorientation和statusbarorientation方向還是原來的方向。
 
4、接著當(dāng)前view controller的 willanimaterotationtointerfaceorientation:duration: 方法將會(huì)被調(diào)用。系統(tǒng)將會(huì)把該方法中執(zhí)行的所有屬性變化放到動(dòng)animation block中。
 
5、執(zhí)行方向旋轉(zhuǎn)的動(dòng)畫。
 
6、最后調(diào)用 didrotatefrominterfaceorientation: 方法,通知view controller旋轉(zhuǎn)動(dòng)畫執(zhí)行完畢。這個(gè)時(shí)候我們可以將第二部隱藏的view再顯示出來。
 
  整個(gè)響應(yīng)過程如下圖所示:
iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法
以上就是uikit下一個(gè)完整的屏幕旋轉(zhuǎn)流程,我們只需要按照提示做出相應(yīng)的處理就可以完美的支持屏幕旋轉(zhuǎn)。
 
 
 
三、注意事項(xiàng)和建議
 
  1)注意事項(xiàng)
 
  當(dāng)我們的view controller隱藏的時(shí)候,設(shè)備方向也可能發(fā)生變化。例如view controller a彈出一個(gè)全屏的view controller b的時(shí)候,由于a完全不可見,所以就接收不到屏幕旋轉(zhuǎn)消息。這個(gè)時(shí)候如果屏幕方向發(fā)生變化,再dismiss b的時(shí)候,a的方向就會(huì)不正確。我們可以通過在view controller a的viewwillappear中更新方向來修正這個(gè)問題。
 
  2)屏幕旋轉(zhuǎn)時(shí)的一些建議
 •在旋轉(zhuǎn)過程中,暫時(shí)界面操作的響應(yīng)。
 •旋轉(zhuǎn)前后,盡量當(dāng)前顯示的位置不變。
 •對(duì)于view層級(jí)比較復(fù)雜的時(shí)候,為了提高效率在旋轉(zhuǎn)開始前使用截圖替換當(dāng)前的view層級(jí),旋轉(zhuǎn)結(jié)束后再將原view層級(jí)替換回來。
 •在旋轉(zhuǎn)后最好強(qiáng)制reload tableview,保證在方向變化以后,新的row能夠充滿全屏。例如對(duì)于有些照片展示界面,豎屏只顯示一列,但是橫屏的時(shí)候顯示列表界面,這個(gè)時(shí)候一個(gè)界面就會(huì)顯示更多的元素,此時(shí)reload內(nèi)容就是很有必要的。

ios:屏幕旋轉(zhuǎn)與transform
itouch,iphone,ipad設(shè)置都是支持旋轉(zhuǎn)的,如果我們的程序能夠根據(jù)不同的方向做出不同的布局,體驗(yàn)會(huì)更好。
 
  如何設(shè)置程序支持旋轉(zhuǎn)呢,通常我們會(huì)在程序的info.plist中進(jìn)行設(shè)置supported interface orientations,添加我們程序要支持的方向,而且程序里面每個(gè)viewcontroller也有方法
 
  supportedinterfaceorientations(6.0及以后)
 
  shouldautorotatetointerfaceorientation(6.0之前的系統(tǒng))
 
  通過viewcontroller的這些方法,我們可以做到更小粒度的旋轉(zhuǎn)控制,如程序中僅僅允許個(gè)別界面旋轉(zhuǎn)。

 
 
 
一、屏幕旋轉(zhuǎn)背后到底做了什么呢?
 
  下面我們看個(gè)簡(jiǎn)單的例子,用xcode新建一個(gè)默認(rèn)的單視圖工程,然后在對(duì)應(yīng)viewcontroller的響應(yīng)旋轉(zhuǎn)后的函數(shù)中輸出一下當(dāng)前view的信息,代碼如下:
 

復(fù)制代碼 代碼如下:


svrotateviewcontroller

 

//
//  svrotateviewcontroller.m
//  svrotatebytransform
//
//  created by  maple on 4/21/13.
//  copyright (c) 2013 maple. all rights reserved.
//

#import "svrotateviewcontroller.h"

@interface svrotateviewcontroller ()

@end

@implementation svrotateviewcontroller

- (void)viewdidload
{
    [super viewdidload];
    // do any additional setup after loading the view, typically from a nib.
   
    self.view.backgroundcolor = [uicolor graycolor];
}

- (void)didreceivememorywarning
{
    [super didreceivememorywarning];
    // dispose of any resources that can be recreated.
}

- (bool)shouldautorotatetointerfaceorientation:(uiinterfaceorientation)interfaceorientation
{
    return yes;
}

- (bool)shouldautorotate
{
    return yes;
}

- (nsuinteger)supportedinterfaceorientations
{
    return uiinterfaceorientationmaskall;
}

- (void)willrotatetointerfaceorientation:(uiinterfaceorientation)tointerfaceorientation duration:(nstimeinterval)duration
{
    nslog(@"uiviewcontroller will rotate to orientation: %d", tointerfaceorientation);
}

- (void)didrotatefrominterfaceorientation:(uiinterfaceorientation)frominterfaceorientation
{
    nslog(@"did rotated to new orientation, view information %@", self.view);
}

@end

 

  查看代碼我們可以發(fā)現(xiàn),我們的viewcontroller支持四個(gè)方向,然后在旋轉(zhuǎn)完成的didrotatefrominterfaceorientation函數(shù)中打印了self.view的信息,旋轉(zhuǎn)一圈我們可以看到如下輸出:
iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法
二、什么是transform
 
  transform(變化矩陣)是一種3×3的矩陣,如下圖所示:
iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法
通過這個(gè)矩陣我們可以對(duì)一個(gè)坐標(biāo)系統(tǒng)進(jìn)行縮放,平移,旋轉(zhuǎn)以及這兩者的任意組著操作。而且矩陣的操作不具備交換律,即矩陣的操作的順序不同會(huì)導(dǎo)致不同的結(jié)果。uiview有個(gè)transform的屬性,通過設(shè)置該屬性,我們可以實(shí)現(xiàn)調(diào)整該view在其superview中的大小和位置。
 
  矩陣實(shí)現(xiàn)坐標(biāo)變化背后的數(shù)學(xué)知識(shí):
iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法
設(shè)x,y分別代表在原坐標(biāo)系統(tǒng)中的位置,x',y'代表通過矩陣變化以后在新的系統(tǒng)中的位置。其中式1就是矩陣變化的公式,對(duì)式1進(jìn)行展開以后就可以得到式2。從式2我們可以清楚的看到(x,y)到(x',y')的變化關(guān)系。
 
  1)當(dāng)c,b,tx,ty都為零時(shí),x' = ax,y' = by;即a,d就分別代表代表x,y方向上放大的比例;當(dāng)a,d都為1時(shí),x' = x,y' = y;這個(gè)時(shí)候這個(gè)矩陣也就是傳說中的cgaffinetransformidentity(標(biāo)準(zhǔn)矩陣)。
 
  2)當(dāng)a,d為1,c,b為零的時(shí)候,x' = x + tx,y' = y + ty;即tx,ty分別代表x,y方向上的平移距離。
 
  3)前面兩種情況就可以實(shí)現(xiàn)縮放和平移了,那么旋轉(zhuǎn)如何表示呢?
 
  假設(shè)不做平移和縮放操作,那么從原坐標(biāo)系中的一點(diǎn)(x,y)旋轉(zhuǎn)α°以后到了新的坐標(biāo)系中的一點(diǎn)(x',y'),那么旋轉(zhuǎn)矩陣如下:
iOS開發(fā)中使用屏幕旋轉(zhuǎn)功能的相關(guān)方法
展開以后就是x' = xcosα - ysinα,y' = xsinα + ycosα;
 
 
 
  實(shí)際應(yīng)用中,我們將這些變化綜合起來,即可完成所有二維的矩陣變化。現(xiàn)在我們?cè)诨剡^頭來看看前面設(shè)備旋轉(zhuǎn)時(shí)的輸出,當(dāng)設(shè)備位于portrait的時(shí)候由于矩陣是標(biāo)準(zhǔn)矩陣,所以沒有進(jìn)行打印。當(dāng)轉(zhuǎn)到uiinterfaceorientationlandscapeleft方向的時(shí)候,我們的設(shè)備是順時(shí)針轉(zhuǎn)了90°(逆時(shí)針為正,順時(shí)針為負(fù)),這個(gè)時(shí)候矩陣應(yīng)該是(cos-90°,sin-90°,-sin-90°,cos-90°,tx,ty),由于未進(jìn)行平移操作所以tx,ty都為0,剛好可以跟我們控制臺(tái)輸出:"<uiview: 0x8075390; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = w+h; layer = <calayer: 0x8074980>>"一致。觀察其他兩個(gè)方向的輸出,發(fā)現(xiàn)結(jié)果均和分析一致。
 
  由此可以發(fā)現(xiàn)屏幕旋轉(zhuǎn)其實(shí)就是通過view的矩陣變化實(shí)現(xiàn),當(dāng)設(shè)備監(jiān)測(cè)到旋轉(zhuǎn)的時(shí)候,會(huì)通知當(dāng)前程序,當(dāng)前程序再通知程序中的window,window會(huì)通知它的rootviewcontroller的,rootviewcontroller對(duì)其view的transform進(jìn)行設(shè)置,最終完成旋轉(zhuǎn)。
 
  如果我們直接將一個(gè)view添加到window上,系統(tǒng)將不會(huì)幫助我們完成旋操作,這個(gè)時(shí)候我們就需要自己設(shè)置該view的transform來實(shí)現(xiàn)旋轉(zhuǎn)了。這種情況雖然比較少,但是也存在的,例如現(xiàn)在很多app做的利用狀態(tài)欄進(jìn)行消息提示的功能就是利用自己創(chuàng)建window并且自己設(shè)置transform來完成旋轉(zhuǎn)支持的,下一篇博客會(huì)介紹如何實(shí)現(xiàn)這種消息通知。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 四虎官网| 羞羞影院午夜男女爽爽影院网站 | 色悠久久久久综合网小说 | 亚洲精品国精品久久99热 | 免费在线观看小视频 | 国产精品成人自拍 | 九九九九九九精品免费 | 天堂bt在线 | 国产综合久久 | 日本javhd | 娇妻被朋友征服中文字幕 | 青青草国产精品久久碰 | 国产全部理论片线观看 | 二次元美女挤奶漫画 | 国产91青青成人a在线 | 视频一区二区 村上凉子 | 国产日韩片 | japanese秘书丝袜 | 九九九精品视频 | bl文全肉高h湿被灌尿 | 黑人操日本妞 | 骚虎最新网址 | 175m美女被网友灌醉啪啪玩脚 | 久久这里只有精品视频9 | 九色PORNY真实丨国产免费 | 国产午夜视频在线观看网站 | 精品久久99麻豆蜜桃666 | 国产毛片在线观看 | 精品国产三级av在线 | 亚洲女同在线观看 | 超级乱淫变态伦短篇小说全集 | 天天做日日爱 | 亚洲精品国产成人 | 99国产小视频 | 国产资源免费观看 | 亚洲一区二区日韩欧美gif | 人人精品久久 | 久久99精品久久久久久园产越南 | 99视频精品全部 在线 | 日日网| ysl蜜桃色成人麻豆 youwu在线影院 |