1. 程式人生 > >ios程式碼新增UIViewController對應的view作為子控制元件

ios程式碼新增UIViewController對應的view作為子控制元件

專案程式碼分析https://github.com/thanklife/iosChangeViewcontroller

這是一個程式碼實現view的例子:主view上有4個控制元件:3個按鈕和一個UIView型別的contentView,其中點選某一個按鈕的時候,就會在contentView上新增子控制元件進行顯示

#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController
{

    IBOutlet UIView *contentView;

    IBOutlet UIButton *firstButton;

    IBOutlet UIButton *secondButton;

    IBOutlet UIButton *thirdButon;

    UIViewController *currentViewController;

}

-(IBAction)onClickbutton:(id)sender;

@end
原始碼部分可見到在xib中需要設定一下三個button的tag id;
#import "MainViewController.h"

#import "FirstViewController.h"

#import "SecondViewController.h"

#import "ThirdViewController.h"

@implementation MainViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle

FirstViewController *firstViewController;
SecondViewController *secondViewController;
ThirdViewController *thirdViewController;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    firstViewController=[[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    [self addChildViewController:firstViewController];

    secondViewController=[[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    [self addChildViewController:secondViewController];

    thirdViewController=[[ThirdViewController alloc] initWithNibName:@"ThirdViewController" bundle:nil];
    [self addChildViewController:thirdViewController];

    [contentView addSubview:thirdViewController.view];

    currentViewController=thirdViewController;

}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(IBAction)onClickbutton:(id)sender
{
    if ((currentViewController==firstViewController&&[sender tag]==1)||(currentViewController==secondViewController&&[sender tag]==2) ||(currentViewController==thirdViewController&&[sender tag]==3) ) {
        return;
    }
    UIViewController *oldViewController=currentViewController;
    switch ([sender tag]) {
        case 1:
        {
            NSLog(@"留言及回覆");
            [self transitionFromViewController:currentViewController toViewController:firstViewController duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{
            }  completion:^(BOOL finished) {
                if (finished) {
                    currentViewController=firstViewController;
                }else{
                    currentViewController=oldViewController;
                }
            }];
}
            break;
        case 2:
        {
            NSLog(@"生日提醒");
            [self transitionFromViewController:currentViewController toViewController:secondViewController duration:1 options:UIViewAnimationOptionTransitionCurlDown animations:^{

            }  completion:^(BOOL finished) {
                if (finished) {
                  currentViewController=secondViewController;
                }else{
                    currentViewController=oldViewController;
                }
            }];
        }
            break;
        case 3:
        {
            NSLog(@"好友申請");
            [self transitionFromViewController:currentViewController toViewController:thirdViewController duration:1 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{

            }  completion:^(BOOL finished) {
                if (finished) {
                     currentViewController=thirdViewController;
                }else{
                    currentViewController=oldViewController;
                }
            }];
        }
            break;
        default:
            break;
    }
}
@end

三個子控制元件都是由UIViewController對應的xib的view形成的,三個子控制元件實現都一致,差別在於背景色不同和 lable 的文字內容不同。這裡僅列出一個的程式碼
#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

@end

#import "FirstViewController.h"

@implementation FirstViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    debugMethod();
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    debugMethod();
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    debugMethod();
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    debugMethod();
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    debugMethod();
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    debugMethod();
}

- (void)willMoveToParentViewController:(UIViewController *)parent {
    debugMethod();
}

- (void)didMoveToParentViewController:(UIViewController *)parent {
    debugMethod();
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

經過這個內容總結:

1、子控制元件中新增 的view 也可有UIViewController,據目前瞭解的情況,這裡的controller初始化後要儲存,不然addSubview方法之後,就會被釋放;

2、在xib中對這些子控制元件UIView的屬性 simulated metrics--》size要設定為Freeform,status bar top bar,bottom bar可以根據情況進行設定。

3、在執行[self addChildViewController:firstViewController];的時候會呼叫firstViewController 的- (void)willMoveToParentViewController:(UIViewController *)parent方法

4、在執行[contentView addSubview:thirdViewController.view];的時候會執行 -[ThirdViewController viewDidLoad];

5、當進行addChildViewController的幾個view進行切換的操作的實現是- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(5_0);

apple文件的註釋內容為:

  This method can be used to transition between sibling child view controllers. The receiver of this method is
  their common parent view controller. (Use [UIViewController addChildViewController:] to create the
  parent/child relationship.) This method will add the toViewController's view to the superview of the
  fromViewController's view and the fromViewController's view will be removed from its superview after the
  transition completes. It is important to allow this method to add and remove the views. The arguments to
  this method are the same as those defined by UIView's block animation API. This method will fail with an
  NSInvalidArgumentException if the parent view controllers are not the same as the receiver, or if the
  receiver explicitly forwards its appearance and rotation callbacks to its children. Finally, the receiver
  should not be a subclass of an iOS container view controller. Note also that it is possible to use the
  UIView APIs directly. If they are used it is important to ensure that the toViewController's view is added
  to the visible view hierarchy while the fromViewController's view is removed.

這裡實現的程式碼是:

            [self transitionFromViewController:currentViewController toViewController:firstViewController duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{
            }  completion:^(BOOL finished) {
                if (finished) {
                    currentViewController=firstViewController;
                }else{
                    currentViewController=oldViewController;
                }
            }];


該方法的執行會讓依次執行:

-[SecondViewController viewDidLoad]
-[ThirdViewController viewWillDisappear:]
-[SecondViewController viewWillAppear:]
-[SecondViewController viewDidAppear:]
-[ThirdViewController viewDidDisappear:]

5,這個程式碼部分新增 #define debugMethod() NSLog(@"%s", __func__)的巨集定義,在 view 的一些方法裡面新增後,非常有利於觀察各個方法的呼叫順序,這裡經過觀察就可以更好的進行程式碼的新增和實現了。


相關推薦

ios程式碼新增UIViewController對應view作為控制元件

專案程式碼分析https://github.com/thanklife/iosChangeViewcontroller 這是一個程式碼實現view的例子:主view上有4個控制元件:3個按鈕和一個UIView型別的contentView,其中點選某一個按鈕的時候,就會在co

02 - 載入XIB(ViewController)後 View控制元件無響應中

02 - 載入XIB(ViewController)後 View的子控制元件無響應中 問題描述 前提 : 自定義XIB:包含若干個Button 理想現象 : 用Button響應相關動作 報錯reason : 無報錯 解決方式 : 強引用XIB中的Cont

GridView中動態新增模板列和其控制元件集合

1 using System; 2 using System.Data; 3 using System.Configuration; 4 using System.Linq; 5 using System.Web; 6 using System.Web.Security; 7 using Sy

iOS開發之xib或storyboard上給UIScrollView新增控制元件約束報錯的問題

當我們在xib或者storyboard中新增UIScrollView並像給其他控制元件設定約束一樣設定好約束後(例如top,leading,tralling,bottom都為0),顯示一切正常,如圖: 但是一旦當我們新增控制元件後就開始報錯(即便設定好約束

iOS開發之在scrollview上新增點選並解決其控制元件的點選無響應(如tableView)

- (void)addTap{ UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:s

iOS中自定義View實現layoutSubviews佈局控制元件

iOS開發中,- (void)layoutSubviews{}方法及相關方法注意點!! ==== ```objectivec - (void)creatAutoLayoutUSE { // 一、layout相關方法 } ``` - (void)layoutSubviews

iOS開發如何在一個透明檢視上新增不透明的控制元件

相信很多同學都會遇到過這個問題, 當我們彈出一個半透明的遮蓋層時, 又想在遮蓋層上加一些子檢視, 這個時候如果你的遮蓋層設定了alpha屬性,  你會驚訝的發現, 載入遮蓋層上的所有子控制元件都是透明

IOS開發學習筆記十五 為UITableView控制元件新增Header和Footer

效果圖:專案地址 新增圖片素材,新增plist檔案,新增名為CZGoods的module檔案 @implementation CZGoods - (instancetype)initWithDict:(NSDictionary *)dict { if

iOS 開發 WKWebView載入網頁,對網頁控制元件進行更改,使用OC新增JS

//獲取載入的網頁 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void

iOS UIView及其控制元件的常用設定

為控制元件新增邊框 view.layer.borderWidth = 1; view.layer.borderColor = [[UIColor blackColor] CGColor]; b

Android動態設定佈局,為LinearLayout動態新增控制元件

View view = getActivity().getLayoutInflater().inflate(R.layout.category_select_popupwindow_right, null); LinearLayout line

IOS ScrollView 控制元件滑動手勢衝突

允許子檢視手勢延時響應 delaysContentTouches設 置為YES, CanCancelContentTouches設定為NO 以上設定了只是達到停頓0.5秒後,子控制元件可以手勢拖動

Android 在程式中動態新增 View 佈局或控制元件

有時我們需要在程式中動態添加布局或控制元件等,下面用程式來展示一下相應的方法: 1、addView 新增View到佈局容器 2、removeView 在佈局容器中刪掉已有的View 3、LayoutParams  設定View的大小位置   下面來看一個demo; pu

UIScrollView新增控制元件約束的一些小總結

之前在使用AutoLayout給UIScrollView進行佈局的時候,總會出現點這樣那樣莫名其妙的問題.我也曾跳坑兩次,掙扎許久最後都以放棄storyboard改為程式碼實現而告終.今天終得正解,遂

ArrayAdapter作為ListView介面卡,ListView作為LinearLayout控制元件時,ListView的item不可點選

知道處於何種原因,如題所述。 解決方法:1. 將RelativeLayout作為ListView的父控制元件。2.用baseAdapter作為ListView的介面卡。 其中使用了各種使ListView的Item獲得焦點的方法都無濟於事,包括如下: 1.listView.s

Android listview控制元件的的點選事件(轉)

1.先看圖,是否是你想要的   2.佈局檔案<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" androi

禁止 ScrollView 在控制元件的佈局改變時自動滾動到最底部

在做專案的時候,遇到了一個問題,就是有下面那樣一個佈局: 某種情況下要動態改變 ViewPager 的高度,但是有時候再改變之後,整個頁面會自動滑動到最底部,而不是保持原有的位置。 解決方法: 重寫scrollview中的如下方法,並將其返回值設為0即可。 @Override

Android自定義View--翻書控制元件(一)

0.前言 最近重看了一遍封神演義,感覺QQ閱讀那個翻書的效果挺好的,準備做一個。上週五下午用了兩個小時只寫了一部分功能,以後有時間再完善 1.分析 先看效果圖 這個空間,說簡單也簡單,說難也難,簡單就在於這個效果主要就是依賴canvas的clippath才見到部分canvas,難就難在裁

重繪ListCtrl中增加控制元件Edit是,在父控制元件失去焦點時,控制元件不進行隱藏

問題:現在有一個listctrl控制元件,需要在某一列上新增一個子控制元件edit。當點選子控制元件(edit)時,子控制元件顯示出來,父控制元件(ListCtrl)已經失去焦點了。此時,要是滑鼠點選的位置不在該控制元件內,edit處於顯示狀態,父控制元件(ListCtrl)是失去焦點狀態。

使用spreadjs作為核心控制元件使用教程(1)

產品介紹。 需求:合約式物流公司的客服每天需要編寫跟蹤表資訊給客戶,在業務系統不健全的情況下,客服的工作是從業務系統複製資料到excel上,然後打電話給司機問到哪裡瞭然後再填在excel上。使用spreadjs做為excel,再在spreadjs的基礎上加上顯示業務系統資訊的功能,從而改善客服