<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      UIViewController的基本概念與生命周期

      UIViewController是iOS頂層視圖的載體及控制器,用戶與程序界面的交互都是由UIViewController來控制的,UIViewController管理UIView的生命周期及資源的加載與釋放。

      UIView與UIWindow共同展示了應用程序的用戶界面。可以將UIView理解成畫布,UIWindow理解成畫框。這兩個類的繼承關系是這樣的:

      NSObject — UIResponder — UIView — UIWindow

      iOS中,所有顯示在界面上的對象都是從UIResponder直接或間接繼承的,UIView和UIWindow也不例外。

      可以將它們之間的關系想象成這樣一個場景:首先會有一個空的畫框(UIWindow),我們在畫框上放置一塊畫布(UIView),然后可以在這個畫布(UIView)上進行繪畫,畫布上可能會被畫上各種元素,例如UILabel、UIButton等。這些元素其實也是一個又一個UIView,它們會有一個層級關系管理,有點相當于Photoshop圖層的概念,層級高的元素會覆蓋住層級低的元素,從而導致層級低的元素被部分或完全遮擋。

      UIWindow

      雖然UIWindow繼承自UIView,但是在模型中,它是一個首席View。UIWindow的主要作用是提供一個區域來顯示UIView,然后將事件分發給UIView。一般情況下,應用程序只有一個UIWindow對象,即使有多個UIWindow對象,也只有一個UIWindow可以接受到用戶的觸屏事件。

      當新建一個最原始的Empty Application工程后,會發現系統在application:didFinishLaunchingWithOptions:方法里已經為我們建好了一個UIWindow,代碼如下:

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
      {
          self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
          // Override point for customization after application launch.
          self.window.backgroundColor = [UIColor whiteColor];
          [self.window makeKeyAndVisible];
          return YES;
      }

      1. 創建一個全屏的window:

      self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

      2. 給window設置背景色:

      self.window.backgroundColor = [UIColor whiteColor];

      3. 給將window設置為KeyWindow并顯示:

      [self.window makeKeyAndVisible];

      假如這個時候通過調試器啟動這個程序,將會收到系統輸出的一個提示:

      Application windows are expected to have a root view controller at the end of application launch

      這個提示表示沒有指定根view controller,我們可以新建一個帶xib文件的ViewController類作為window的rootViewController:

      MyFirstViewController *myVC = [[MyFirstViewController alloc] init];
      self.window.rootViewController = myVC;

      P.s. 這里有一點需要注意,無論你怎么修改ViewController類實例的尺寸,都會強制鋪滿整個window,文檔里是這樣解釋的:”If a view controller is owned by a window object, it acts as the window’s root view controller. The view controller’s root view is added as a subview of the window and resized to fill the window.

      UIView

      UIView有下面這些基礎概念:

      • UIViewController的view屬性擁有一個UIView。
      • UIView中可以包含多個UIView(subviews)。
      • UIView可以通過superview屬性訪問父UIView。
      • 如果是UIWindow的子元素,則可以通過Window屬性訪問UIWindow。

      UIView中常用的結構體:

      CGPoint point = CGPointMake(x, y); //坐標
      CGSize size = CGSizeMake(width, height); //大小
      CGRect rect = CGRectMake(x, y, width, height); //位置和大小

      UIView的常用屬性:

      frame — 相對父視圖的位置和大小

      bounds — 相對自身的位置和大小,所以bounds的x和y永遠為0

      center — 子視圖的中點坐標相對父視圖的位置

      transform — 可以通過這個屬性控制視圖的放大縮小和旋轉

      superview — 獲取父視圖

      subviews — 獲取所有子視圖

      alpha — 視圖的透明度(0 - 1)

      tag — 視圖的標志,設置了tag后,可以通過viewWithTag方法獲取這個視圖

      userInteractionEnabled — 是否相應用戶交互事件

      通過transform屬性來對視圖進行縮放、旋轉和平移

      //獲取當前transform
      CGAffineTransform transform = self.lblSeg.transform;
      
      //縮放
      self.lblSeg.transform = CGAffineTransformMakeScale(.5, .5);
      
      //在一個transform的基礎上再縮放
      self.lblTest.transform = CGAffineTransformScale(transform, 0.5, 0.5);
      
      //旋轉(弧度制)
      self.lblSeg.transform = CGAffineTransformMakeRotation(M_2_PI);
      
      //在一個transform的基礎上再旋轉
      self.lblTest.transform = CGAffineTransformRotate(transform,M_2_PI);
      
      //平移
      self.lblSeg.transform = CGAffineTransformMakeTranslation(100, 100);
      
      //在一個transform的基礎上再平移
      self.lblTest.transform = CGAffineTransformTranslate(transform, 100, 100);

      UIView的常用方法:

      初始化視圖

      - (id)initWithFrame:(CGRect)aRect

      UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(10.0, 20.0, 150.0, 100.0)];

       

      將視圖從父視圖中移除

      - (void)removeFromSuperview

      [self.lblTest removeFromSuperview];

       

      插入一個視圖到指定位置

      - (void)insertSubview:(UIView *)view atIndex:(NSInteger)index

      NSInteger myIndex = 0;
      
      if(self.myView1.subviews.count>0)
      {
          myIndex = self.myView1.subviews.count;
      }
      
      [self.myView1 insertSubview:self.lblTest atIndex:myIndex];

       

      將index1和index2位置的兩個視圖互換位置

      - (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2

      NSInteger index1 = [self.view.subviews indexOfObject:self.lblTest1];
      
      NSInteger index2 = [self.view.subviews indexOfObject:self.lblTest2];
      
      [self.view exchangeSubviewAtIndex:index1 withSubviewAtIndex:index2];

       

      添加子視圖

      - (void)addSubview:(UIView *)view

      [self.myView1 addSubview:self.lblTest];

       

      插入視圖到指定位置

      - (void)insertSubview:(UIView *)view atIndex:(NSInteger)index

      [self.view insertSubview:self.lblTest atIndex:0];

       

      插入視圖到指定視圖的下面

      - (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview

      [self.view insertSubview:self.lblTest1 belowSubview:self.lblTest2];

       

      插入視圖到指定視圖的上面

      - (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview

      [self.view insertSubview:self.lblTest1 aboveSubview:self.lblTest2];

       

      將指定子視圖移到最頂層

      - (void)bringSubviewToFront:(UIView *)view

      [self.view bringSubviewToFront:self.lblTest];

       

      將指定子視圖移到最底層

      - (void)sendSubviewToBack:(UIView *)view

      [self.view sendSubviewToBack:self.lblTest];

       

      根據視圖的tag查找視圖

      - (UIView *)viewWithTag:(NSInteger)tag

      [self.lblTest setTag:5];
      [self.view viewWithTag:5].alpha = 0;

       

      取得視圖下的所有子視圖

      @property(nonatomic, readonly, copy) NSArray *subviews

      NSArray *arrView = [self.view subviews];
      
      for (UIView *view1 in arrView)
      {
          NSLog(@"%@",view1);
      }

       

      UIScreen

      UIScreen類代表了屏幕,通過這個類我們可以獲取一些關于屏幕的內容:

      返回帶有狀態欄的Rect

      CGRect bounds = [UIScreen mainScreen].bounds;
      
      NSLog(@"%.0f,%.0f,%.0f,%.0f",bounds.origin.x,
                           bounds.origin.y,
                           bounds.size.width,
                           bounds.size.height
            );

      在4英寸設備的屏幕下測試,將打印出0,0,320,568

       

      返回不帶狀態欄的Rect

      CGRect bounds = [[UIScreen mainScreen] applicationFrame];
      
      NSLog(@"%.0f,%.0f,%.0f,%.0f",bounds.origin.x,
                           bounds.origin.y,
                           bounds.size.width,
                           bounds.size.height
            );

      在4英寸設備的屏幕下測試,將打印出0,20,320,548

      無論是帶狀態欄還是不帶狀態欄獲得的Rect,都是相對于設備屏幕來說的,所以當返回不帶狀態欄的Rect時,y坐標為20(狀態欄的高度為20),而高度減少了20,為568-20=548。

      下面這個方法可以獲得狀態欄(StatusBar)的位置和大小:

      CGRect rect = [[UIApplication sharedApplication] statusBarFrame];
      
      NSLog(@"%.0f,%.0f,%.0f,%.0f",rect.origin.x,
                           rect.origin.y,
                           rect.size.width,
                           rect.size.height
            );

      在4英寸設備的屏幕下測試,將打印出0,0,320,20

       

      生命周期

      我們建立一個簡單的模型來測試生命周期:新建兩個ViewController,一個是主視圖控制器(main ViewController,以下簡稱mainVC),一個是副視圖控制器(sub ViewController,以下簡稱subVC),在mainVC里點擊一個Button,以modal方式切換至subVC,然后在subVC里點擊另一個Button關閉subVC并返回mainVC。我們將這兩個控制器的每個狀態都打印出來,各個階段的執行如下:

      case 1. 第一次運行app:

      main loadView

      main viewDidLoad

      main viewWillAppear

      main viewDidAppear

       

      case 2. 在mainVC里點擊Button,以modal方式切換至subVC:

      sub loadView

      sub viewDidLoad

      main viewWillDisappear

      sub viewWillAppear

      sub viewDidAppear

      main viewDidDisappear

       

      case 3. 在subVC里點擊Button關閉subVC并返回mainVC

      sub viewWillDisappear

      main viewWillAppear

      main viewDidAppear

      sub viewDidDisappear

      sub dealloc

       

      當一個視圖控制器被創建,并在屏幕上顯示的時候代碼的執行順序:

      step 1:alloc 創建對象,分配空間

      step 2:init (initWithNibName) 初始化對象

      step 3:loadView 從nib載入視圖 ,通常這一步不需要去干涉。除非你沒有使用xib文件創建視圖

      step 4:viewDidLoad 載入完成,可以進行自定義數據以及動態創建其他控件

      step 5:viewWillAppear 視圖將出現在屏幕之前,馬上這個視圖就會被展現在屏幕上了

      step 6:viewDidAppear 視圖已在屏幕上渲染完成

       

      當一個視圖控制器被移除屏幕并且銷毀的時候的執行順序:

      step 1:viewWillDisappear 視圖將被從屏幕上移除之前執行

      step 2:viewDidDisappear 視圖已經被從屏幕上移除,用戶看不到這個視圖了

      step 3:dealloc 視圖被銷毀

       

      這里需要說一下loadView與viewDidLoad的區別:當loadView時,還沒有view;而viewDidLoad時,view已經創建好了。詳細的加載循環:

      step 1:程序請求ViewController的view屬性

      step 2:如果view在內存中,則直接加載;如果不存在,則調用loadView方法

      step 3:loadView方法執行如下方法:

      • 如果重載了這個方法,則必須創建必要的UIView并且將一個非nil值傳給ViewController的view屬性。
      • 如果沒有重載這個方法,ViewController會默認使用自己的nibName和nibBundle屬性嘗試從nib文件加載view。如果沒有找到nib文件,它嘗試尋找一個與ViewController類名匹配的nib文件。
      • 如果沒有可用的nib文件,那么它創建一個空的UIView作為它的view。

      最后還要考慮一個重要的情況:內存不足警告。當程序收到內存警告的時候,會調用每一個ViewController的didReceiveMemoryWarning方法,我們需要做出相應,釋放程序中暫時不需要的資源;通常都會重寫該方法,但記得重寫的時候要調用super的該方法。

      iOS3.0 - iOS6.0期間,didReceiveMemoryWarning方法會判斷當前ViewController的view是否顯示在window上,如果沒有顯示在window上,則didReceiveMemoryWarning會自動將ViewController的view以及其所有子view全部銷毀,然后調用View Controller的viewDidUnload方法。但是從iOS6.0開始,viewDidUnload和viewWillUnload這兩個方法已被廢除,收到low-memory時系統不會釋放view,而只是釋放controller的resource。

      一種常見處理內存警告的方式:

      - (void)didReceiveMemoryWarning
      {
          [super didReceiveMemoryWarning];
          
          float ver = [[[UIDevice currentDevice] systemVersion] floatValue];
          
          if(ver >= 6.0f)
          {
              if(self.isViewLoaded && !self.view.window)
              {
                  self.view = nil; //確保下次重新加載
              }
          }
      }

      上面的代碼先取得當前iOS系統的版本號,如果是iOS6.0或以上版本,進一步判斷視圖是否被裝載進內存,并且是否為當前視圖,在這兩個條件都滿足(已經裝載進內存&&不是當前視圖)時,將self.view設置為nil,這樣就能保證再調用該ViewController時,loadView和viewDidLoad被再次調用。

      我們在xcode調試器里模擬內存警告,監控此時切換的狀態:

      case 4. 當已切換至subVC,模擬內存警告,并返回mainVC,不處理didReceiveMemoryWarning。

      Received memory warning.

      main didReceiveMemoryWarning

      sub didReceiveMemoryWarning

      sub viewWillDisappear

      main viewWillAppear

      main viewDidAppear

      sub viewDidDisappear

      sub dealloc

       

      case 5. 當已切換至subVC,模擬內存警告,并返回mainVC,處理didReceiveMemoryWarning。

      Received memory warning.

      main didReceiveMemoryWarning

      sub didReceiveMemoryWarning

      main loadView

      main viewDidLoad

      sub viewWillDisappear

      main viewWillAppear

      main viewDidAppear

      sub viewDidDisappear

      sub dealloc

       

      可以很明顯的看出,當處理了didReceiveMemoryWarning后,重新執行了非當前視圖的loadView和viewDidLoad方法。

      posted @ 2014-07-25 17:10  CoderWayne  閱讀(15094)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 免费看又黄又无码的网站| 亚洲美免无码中文字幕在线| 亚洲精品无码成人A片九色播放| 日韩人妻精品中文字幕专区| 于都县| 亚洲中文字幕国产综合| 亚洲鸥美日韩精品久久| 2020年最新国产精品正在播放| 国产大尺度一区二区视频| 国产91精选在线观看| 欧美成人午夜精品免费福利| 少妇无码太爽了在线播放| 精品国产午夜福利在线观看| 中文字幕人妻日韩精品| 男女爽爽无遮挡午夜视频| 国产成人无码A区在线观看视频| 国产精品视频午夜福利| 国产亚洲精品成人av久| 亚洲狠狠婷婷综合久久久| 亚洲色最新高清AV网站| 无码日韩做暖暖大全免费不卡| 亚洲一区二区三区啪啪| 1精品啪国产在线观看免费牛牛| 亚洲精品国产中文字幕| 少妇被躁爽到高潮| 久久精品国产久精国产果冻传媒 | 中文字幕亚洲人妻系列| 久久精品国产99国产精品澳门| 久久精品国产九一九九九| 国产精品一区在线蜜臀| 97无码人妻福利免费公开在线视频| 国产午夜福利一区二区三区 | 精品无码成人片一区二区| 亚洲av免费成人在线| 久久国产成人高清精品亚洲| 国产亚欧女人天堂AV在线| 亚洲AV日韩精品久久久久| 精品国产日韩亚洲一区| 国产高在线精品亚洲三区| 国产成人精品亚洲午夜| 成年黄页网站大全免费无码|