需求:一个界面需要加载多个控制器,最底部用UIScrollView来实现滑动,通过自定义顶部的view来实现点击跳转。
问题:子控制器创建的时候默认带了xib,如果不在xib里面直接拖东西,控制器的view那么添加到UIScrollView上的宽度就是正确的 ,
但是如果添直接在控制器的xib拖了东西之后,控制器的view添加到UIScrollView上的宽度就会是xib的宽度。
图片:
如图,在vc01中的xib中拖了一个UITableView并设置约束距离左、右、下都为0,距离顶部一定距离。然后将控制器vc01作为子控制器加载到UIScrollView界面的控制器中。
打印结果:打印出来的这个vc01控制器的view的宽度是vc01 width = 375.000000
附上代码在主界面的代码,添加的子控制器就是带有xib的控制器:
@interface HomeViewController ()<UIScrollViewDelegate>
/** 标签底部的红色指示器 */
@property (nonatomic, weak) UIView * indicatorView;
/** 当前选中的按钮 */
@property (nonatomic, weak) UIButton * selectedButton;
/** 顶部所有标签 */
@property (nonatomic, weak) UIView * titlesView;
/** 底部的所有内容 */
@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);
}
/**
*设置顶部的标签栏
*/
- (void)setupTitlesView{
// 标签栏整体
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;
// 内部的子标签
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];
//默认选中第一个按钮
if (i ==0 ) {
button.enabled = NO;
self.selectedButton = button;
// 让按钮内部的label根据文字的内容来计算尺寸
[button.titleLabel sizeToFit];
self.indicatorView.width = button.titleLabel.width;
self.indicatorView.centerX = button.centerX;
}
}
[titlesView addSubview:indicatorView];
}
/**
* 按钮的点击事件
*/
- (void)titleClick:(UIButton *)button{
// 修改按钮的状态
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];
}
/**
* 设置底部的ScorllView
*/
- (void)setupContentView{
// 不要自动调整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];
// 计算方式就是 宽带 * 子控制器的个数
contentView.contentSize = CGSizeMake(contentView.width * self.childViewControllers.count, 0);
self.contentView = contentView;
// 添加第一个控制器的view
[self scrollViewDidEndScrollingAnimation:contentView];
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
// 当前的索引
NSInteger index = scrollView.contentOffset.x / scrollView.width;
// 取出子控制器
UIViewController * vc = self.childViewControllers[index];
vc.view.x = scrollView.contentOffset.x;
vc.view.y = 0; // 设置控制器的view的y值为0(默认为20)
vc.view.height = scrollView.height; // 设置控制器的view的height的值为整个屏幕的高度(默认是比屏幕高度少20)
[scrollView addSubview:vc.view];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
[self scrollViewDidEndScrollingAnimation:scrollView];
// 点击按钮
NSInteger index = scrollView.contentOffset.x / scrollView.width;
[self titleClick:self.titlesView.subviews[index]];
}
求大神指教。万分感谢。
原因是你并没有完全指定
childViewController
的frame,所以它默认是你的xib视图大小,并不会去适配在
addChildViewController
后调用类似如下方法以适配宽高另外,请尽量不要主动调用代理方法,满足相应条件它会自己走的