【问题标题】:Cannot show UICollectionView with Segmented Control无法使用分段控件显示 UICollectionView
【发布时间】:2016-04-11 07:06:03
【问题描述】:

在我的主视图控制器中,下面有一个分段控件和一个容器视图。每当我切换分段控件时,我都想更改容器视图。当我切换选项卡时,我可以看到正在加载的视图(在 viewDidload 中打印),但是,我发现它不适用于 collectionViewDataSource 的数据源。有什么想法吗?

// Main View
let videoViewController = VideoViewController()
let photoViewController = PhotoViewController()


private var activeViewController: UIViewController? {
    didSet {
        removeInactiveViewController(oldValue)
        updateActiveViewController()
    }
}

@IBOutlet weak var containerView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    activeViewController = videoViewController

}

@IBAction func segmentDidChanged(sender: UISegmentedControl) {
    if sender.selectedSegmentIndex == 0 {
        print("\(sender.titleForSegmentAtIndex(0)!) Selected")
        activeViewController = videoViewController

    } else if sender.selectedSegmentIndex == 1 {
        print("\(sender.titleForSegmentAtIndex(1)!) Selected")
        activeViewController = photoViewController
    }
}


private func removeInactiveViewController(inactiveViewController: UIViewController?) {
    if let inActiveVC = inactiveViewController {
        // call before removing child view controller's view from hierarchy
        inActiveVC.willMoveToParentViewController(nil)

        inActiveVC.view.removeFromSuperview()

        // call after removing child view controller's view from hierarchy
        inActiveVC.removeFromParentViewController()
    }
}

private func updateActiveViewController() {
    if let activeVC = activeViewController {
        // call before adding child view controller's view as subview
        addChildViewController(activeVC)

        activeVC.view.frame = containerView.bounds
        containerView.addSubview(activeVC.view)

        // call before adding child view controller's view as subview
        activeVC.didMoveToParentViewController(self)
    }
}

// PhotoView
@IBOutlet weak var collectionView: UICollectionView!


override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    print("HI")
}
extension PhotoViewController : UICollectionViewDataSource {

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 2
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 2
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as!PhotoCollectionViewCell
    cell.backgroundColor = UIColor.blackColor()
    // Configure the cell
    cell.imgView.image = UIImage(named: "test")
    return cell
}
}

当我将 PhotoViewController 作为初始控制器时,它可以工作。

【问题讨论】:

  • 我认为 collectionView 没有作为视图加载到 addsubview 上。
  • 在将其视图添加到容器的子视图之前,在 updateActiveViewController 方法中尝试 activeVC.collectionView.reloadData()

标签: ios swift uisegmentedcontrol


【解决方案1】:

我使用过 UIContainerView 和 UISegmentControl,如果你使用 ContainerView 显示单个 UIViewController 已经发布并且链接如下,

When I add a UIContainerView to a view controller it's type is UIView. How do I get to the viewcontroller for the embedded view?

或者如果你使用 ContainerView 显示两个 UIViewController 当或者单击 UISegmentControl 时,显示单个 viewcontroller 代码如下,

如果你创建了storyboard,那么去MainViewController类并创建outlet是

@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentControl;
@property (weak, nonatomic) UIViewController *currentViewController;

ViewDidLoad 方法:

UIFont *font = [UIFont boldSystemFontOfSize:16.0f];
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font
                                                           forKey:UITextAttributeFont];
    [segmentControl setTitleTextAttributes:attributes
                                    forState:UIControlStateNormal];

    _currentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstViewController"];
    _currentViewController.view.layer.cornerRadius = 8.0f;
    _currentViewController.view.translatesAutoresizingMaskIntoConstraints = NO;

    [self addChildViewController:_currentViewController];
    [self addSubview:_currentViewController.view toView:_containerView];

下面给出UISegmentController方法,

-(IBAction)indexChanged:(UISegmentedControl *)sender
{
    if (sender.selectedSegmentIndex == 0) {
        UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstViewController"];
        newViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
        [self cycleFromViewController:self.currentViewController toViewController:newViewController];
        self.currentViewController = newViewController;
    }
    else if (sender.selectedSegmentIndex == 1)
    {
        UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
        newViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
        [self cycleFromViewController:self.currentViewController toViewController:newViewController];
        self.currentViewController = newViewController;
    }
}

而这两个视图相关的方法是,

- (void)addSubview:(UIView *)subView toView:(UIView*)parentView {
    [parentView addSubview:subView];

    NSDictionary * views = @{@"subView" : subView,};
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subView]|"
                                                                   options:0
                                                                   metrics:0
                                                                     views:views];
    [parentView addConstraints:constraints];
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subView]|"
                                                          options:0
                                                          metrics:0
                                                            views:views];
    [parentView addConstraints:constraints];
}

- (void)cycleFromViewController:(UIViewController*) oldViewController
               toViewController:(UIViewController*) newViewController {
    [oldViewController willMoveToParentViewController:nil];
    [self addChildViewController:newViewController];
    [self addSubview:newViewController.view toView:self.containerView];
    [newViewController.view layoutIfNeeded];

    // set starting state of the transition
    newViewController.view.alpha = 0;

    [UIView animateWithDuration:0.5
                     animations:^{
                         newViewController.view.alpha = 1;
                         oldViewController.view.alpha = 0;
                     }
                     completion:^(BOOL finished) {
                         [oldViewController.view removeFromSuperview];
                         [oldViewController removeFromParentViewController];
                         [newViewController didMoveToParentViewController:self];
                     }];
}

如果您使用这些代码或者在单击 SegmentControl 时从 UIContainerView 打开 ViewController,如果从 FirstViewController 工作 CollectionView 并且它为我工作!

希望对您有所帮助..

【讨论】:

  • 我可以使用分段控制器切换容器中的两个视图,但是,如果我添加的视图是 collectionviewController,我会收到一条错误消息。
  • addsubView 中出现错误消息:*** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'UICollectionView 必须使用非零布局参数初始化'
  • 如果在使用 uitableview 的同时使用分段控件切换容器中的两个视图,它对我来说工作正常,我认为你 collectionview 出现了一些错误,它的布局问题,我在下面给出了解决方案link
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多