鍍金池/ 問答/C  iOS/ iOS scrollview中嵌套用xib寫的UIViewController

iOS scrollview中嵌套用xib寫的UIViewController 大小不對

需求:一個界面需要加載多個控制器,最底部用UIScrollView來實(shí)現(xiàn)滑動,通過自定義頂部的view來實(shí)現(xiàn)點(diǎn)擊跳轉(zhuǎn)。
問題:子控制器創(chuàng)建的時候默認(rèn)帶了xib,如果不在xib里面直接拖東西,控制器的view那么添加到UIScrollView上的寬度就是正確的 ,
但是如果添直接在控制器的xib拖了東西之后,控制器的view添加到UIScrollView上的寬度就會是xib的寬度。

圖片:
clipboard.png

如圖,在vc01中的xib中拖了一個UITableView并設(shè)置約束距離左、右、下都為0,距離頂部一定距離。然后將控制器vc01作為子控制器加載到UIScrollView界面的控制器中。

打印結(jié)果:打印出來的這個vc01控制器的view的寬度是vc01 width = 375.000000

附上代碼在主界面的代碼,添加的子控制器就是帶有xib的控制器:

@interface HomeViewController ()<UIScrollViewDelegate>
/** 標(biāo)簽底部的紅色指示器 */
@property (nonatomic, weak) UIView  * indicatorView;
/** 當(dāng)前選中的按鈕 */
@property (nonatomic, weak) UIButton * selectedButton;
/** 頂部所有標(biāo)簽 */
@property (nonatomic, weak) UIView  * titlesView;
/** 底部的所有內(nèi)容 */
@property (nonatomic, weak) UIScrollView  * contentView;
@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor clearColor];
    
    [self setupChildVCs];
    
    [self setupTitlesView];
    
    [self setupContentView];
}

- (void)viewDidLayoutSubviews{
    // 2. 在這里拿到的寬度是正確的
    NSLog(@"layo_self.view.frame.size.width = %f", self.view.bounds.size.width);
}

/**
 * 初始化子控制器
 */
- (void)setupChildVCs{
    
    Test01ViewController * vc01 = [[Test01ViewController alloc]init];
    vc01.title = @"vc01";
    vc01.view.backgroundColor = [UIColor redColor];
    [self addChildViewController:vc01];
    NSLog(@"vc01 width = %f", vc01.view.bounds.size.width);
    
    Test02ViewController * vc02 = [[Test02ViewController alloc]init];
    vc02.title = @"vc02";
    vc02.view.backgroundColor = [UIColor yellowColor];
    [self addChildViewController:vc02];
    NSLog(@"vc02 width = %f", vc02.view.bounds.size.width);
}

/**
 *設(shè)置頂部的標(biāo)簽欄
 */
- (void)setupTitlesView{
    
    // 標(biāo)簽欄整體
    UIView * titlesView = [[UIView alloc]init];
//    titlesView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.7];
    titlesView.backgroundColor = [UIColor blueColor];
//    titlesView.width = self.view.width; // 寬度
    titlesView.width = [UIScreen mainScreen].bounds.size.width;
    titlesView.height = TitlesViewH;
    titlesView.y = TitlesViewY;
    titlesView.x = 0; // 可以不寫
    [self.view addSubview:titlesView];
    self.titlesView = titlesView;
    
    // 底部的紅色指示器
    UIView * indicatorView = [[UIView alloc]init];
    indicatorView.backgroundColor = [UIColor redColor];
    indicatorView.height = 2;
    indicatorView.tag = -1;
    indicatorView.y = titlesView.height - indicatorView.height;
    self.indicatorView = indicatorView;
    
    // 內(nèi)部的子標(biāo)簽
    CGFloat width = titlesView.width / self.childViewControllers.count;
    NSLog(@"width = %f, all width = %f", width, self.view.width);
    CGFloat height = titlesView.height;
    for (NSInteger i = 0; i < self.childViewControllers.count; i++) {
        
        UIButton * button = [[UIButton alloc]init];
        button.tag = i;
        button.height = height;
        button.width = width;
        button.x = i * width;
        
        UIViewController * vc = self.childViewControllers[i];
        [button setTitle:vc.title forState:UIControlStateNormal];
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor redColor] forState:UIControlStateDisabled];
        button.titleLabel.font = [UIFont systemFontOfSize:14];
        [button addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];
        [titlesView addSubview:button];
        
        //默認(rèn)選中第一個按鈕
        if (i ==0 ) {

            button.enabled = NO;
            self.selectedButton = button;
            
            // 讓按鈕內(nèi)部的label根據(jù)文字的內(nèi)容來計(jì)算尺寸
            [button.titleLabel sizeToFit];
            self.indicatorView.width = button.titleLabel.width;
            self.indicatorView.centerX = button.centerX;
        }
    }
    [titlesView addSubview:indicatorView];
}

/**
 * 按鈕的點(diǎn)擊事件
 */
- (void)titleClick:(UIButton *)button{
    
    // 修改按鈕的狀態(tài)
    self.selectedButton.enabled = YES;
    button.enabled = NO;
    self.selectedButton = button;
    
    // 動畫
    [UIView animateWithDuration:0.15 animations:^{
        
        self.indicatorView.width = button.titleLabel.width;
        self.indicatorView.centerX = button.centerX;
    }];
    
    // 滾動
    CGPoint offset = self.contentView.contentOffset;
    offset.x = button.tag * self.contentView.width;
    [self.contentView setContentOffset:offset animated:YES];
}

/**
 * 設(shè)置底部的ScorllView
 */
- (void)setupContentView{
    
    // 不要自動調(diào)整inset
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    UIScrollView * contentView = [[UIScrollView alloc]init];
    contentView.frame = self.view.frame;
    contentView.delegate = self;
    contentView.pagingEnabled = YES;
    [self.view insertSubview:contentView atIndex:0];
    // 計(jì)算方式就是 寬帶 * 子控制器的個數(shù)
    contentView.contentSize = CGSizeMake(contentView.width * self.childViewControllers.count, 0);
    self.contentView = contentView;
    
    // 添加第一個控制器的view
    [self scrollViewDidEndScrollingAnimation:contentView];
}

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    
    // 當(dāng)前的索引
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    
    // 取出子控制器
    UIViewController * vc = self.childViewControllers[index];
    vc.view.x = scrollView.contentOffset.x;
    vc.view.y = 0; // 設(shè)置控制器的view的y值為0(默認(rèn)為20)
    vc.view.height = scrollView.height; // 設(shè)置控制器的view的height的值為整個屏幕的高度(默認(rèn)是比屏幕高度少20)
    [scrollView addSubview:vc.view];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self scrollViewDidEndScrollingAnimation:scrollView];
    
    // 點(diǎn)擊按鈕
    NSInteger index = scrollView.contentOffset.x / scrollView.width;
    [self titleClick:self.titlesView.subviews[index]];
}

求大神指教。萬分感謝。

回答
編輯回答
笨笨噠

原因是你并沒有完全指定childViewController的frame,所以它默認(rèn)是你的xib視圖大小,并不會去適配
addChildViewController后調(diào)用類似如下方法以適配寬高


#pragma mark- 處理ChildViewController
/// 適配子視圖控制器
- (void)fitFrameForChildViewController:(UIViewController *)childViewController{
    //[self.view layoutIfNeeded];
    CGRect frame = self.view.frame;
    frame.origin.y = 0;
    childViewController.view.frame = frame;
}

另外,請盡量不要主動調(diào)用代理方法,滿足相應(yīng)條件它會自己走的

2017年2月18日 07:25