工作生活

通过ChildViewController管理子视图控制器

2019-07-04  本文已影响0人  CocoaJason
Simulator Screen Shot - iPhone Xʀ - 2019-07-04 at 21.53.09.png

期初是通过向collectionView的cell中addSubview,并且通过设置ContenOffset或者ScrollToItem的形式实现,
但是遇到了一些问题,比如
1.子视图控制器的···viewWillAppear和viewWillDisappear···方法不会调用

后又通过addChildViewController的方式实现

1、创建子视图控制器数组,并且向其中添加元素

 [self.childVcAry addObject:childVc];

设置好每一个childVc的view的frame

childVc.view.frame = CGRectMake(0, 100, ScreenWitdh, ScreenHeight - 100);

2.先向self.view中添加第一个子视图控制器(addChildViewController)

  ChildViewController *firstVc = self.childVcAry.firstObject;
    firstVc.label.text = @"0";
    [self addChildViewController:firstVc];
    self.currentChildVc = firstVc;
    [firstVc didMoveToParentViewController:self];
    [self.view addSubview:firstVc.view];

3.切换子视图控制器

- (void)changeVCWithOld:(ChildViewController *)oldController
          newController:(ChildViewController *)newController {
    if (![self.currentChildVc isEqual:newController]) {
        [self addChildViewController:newController];
        [self transitionFromViewController:oldController toViewController:newController duration:0.3 options:(UIViewAnimationOptionShowHideTransitionViews) animations:^{
        
        } completion:^(BOOL finished) {
            if (finished) {
                [newController didMoveToParentViewController:self];
                [oldController willMoveToParentViewController:nil];
                [oldController removeFromParentViewController];
                self.currentChildVc = newController;
            }
        }];
    }
}

···完整代码如下


#define ScreenWitdh [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height

@interface ChildViewController : UIViewController

@property (nonatomic, strong) UILabel *label;

@end

@implementation ChildViewController

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

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

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.label = [[UILabel alloc] init];
    self.label.textColor = [UIColor redColor];
    self.label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:self.label];
    [self.label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(UIEdgeInsetsZero);
    }];
}



@end

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray <ChildViewController *>*childVcAry;
@property (nonatomic, strong) ChildViewController *currentChildVc;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.childVcAry = [NSMutableArray array];
    CGFloat itemWidth = ScreenWitdh / 4;
    for (NSInteger idx = 0 ; idx < 4; idx ++ ) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(itemWidth * idx, 0,itemWidth , 100);
        button.tag = idx;
        [button setTitle:[@(idx) stringValue] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor grayColor] forState:UIControlStateSelected];
        button.adjustsImageWhenHighlighted = NO;
        [button addTarget:self action:@selector(handleButtonClick:) forControlEvents:UIControlEventTouchUpInside];
        button.selected = idx == 0;
        [self.view addSubview:button];
        
        ChildViewController *childVc = [[ChildViewController alloc] init];
        childVc.label.text = [@(idx) stringValue];
        childVc.view.frame = CGRectMake(0, 100, ScreenWitdh, ScreenHeight - 100);
        [self.childVcAry addObject:childVc];
    }
    
    ChildViewController *firstVc = self.childVcAry.firstObject;
    firstVc.label.text = @"0";
    [self addChildViewController:firstVc];
    self.currentChildVc = firstVc;
    [firstVc didMoveToParentViewController:self];
    [self.view addSubview:firstVc.view];
    
    UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGes:)];
    [self.view addGestureRecognizer:panGes];
}

- (void)handlePanGes:(UIPanGestureRecognizer *)panGes {
    static CGPoint startPoint;
    static CGPoint currentPoint;
    switch (panGes.state) {
        case UIGestureRecognizerStateBegan:{
            startPoint = [panGes translationInView:self.currentChildVc.view];
            currentPoint = [panGes translationInView:self.currentChildVc.view];
        }
            break;
        case UIGestureRecognizerStateChanged:
        {
            currentPoint = [panGes translationInView:self.currentChildVc.view];
        }break;
        case UIGestureRecognizerStateEnded:
        {
            CGPoint endPoint = [panGes translationInView:self.currentChildVc.view];
            CGFloat xChange = endPoint.x - startPoint.x;
            CGFloat yChange = endPoint.y - startPoint.y;
            if (fabs(yChange) < 30) {
                if (fabs(xChange) > 30) {
                    NSInteger currentIndex = [self.childVcAry indexOfObject:self.currentChildVc];
                    NSInteger oldIndex = currentIndex;
                    currentIndex -= xChange / fabs(xChange);
                    currentIndex = MAX(currentIndex, 0);
                    currentIndex = MIN(currentIndex, self.childVcAry.count -1);
                    
                    ChildViewController *oldController = self.childVcAry[oldIndex];
                    oldController.label.text = [@(oldIndex) stringValue];
                    ChildViewController *newController = self.childVcAry[currentIndex];
                    newController.label.text = [@(currentIndex) stringValue];
                    
                    [self changeVCWithOld:oldController newController:newController];
                    
                }
            }
        }
            break;
    }
}

- (void)handleButtonClick:(UIButton *)button {
    static UIButton *currentButton;
    if (currentButton != button) {
        [self.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj isKindOfClass:[UIButton class]]) {
                [(UIButton *)obj setSelected:[button isEqual:obj]];
            }
        }];
        NSInteger idx = button.tag;
        ChildViewController *newController = self.childVcAry[idx];
        newController.label.text = [@(idx) stringValue];
        [self changeVCWithOld:self.currentChildVc newController:newController];
    } else {
        
    }
    currentButton = button;
}

- (void)changeVCWithOld:(ChildViewController *)oldController
          newController:(ChildViewController *)newController {
    if (![self.currentChildVc isEqual:newController]) {
        [self addChildViewController:newController];
        [self transitionFromViewController:oldController toViewController:newController duration:0.3 options:(UIViewAnimationOptionShowHideTransitionViews) animations:^{
        
        } completion:^(BOOL finished) {
            if (finished) {
                [newController didMoveToParentViewController:self];
                [oldController willMoveToParentViewController:nil];
                [oldController removeFromParentViewController];
                self.currentChildVc = newController;
            }
        }];
    }
}

能够通过简单手势实现左右切换,但是并未添加类似scrollView的动画,假如您有任何问题,欢迎指出!

上一篇 下一篇

猜你喜欢

热点阅读