2017-04-13 84 views
0

我有两个ViewControllers - Slider & Foo。 我加入Slider作为Foosubview并设置它的内部Foo VC框架,但Slider的框架不会改变 - >我可以看到,只有x & y应用。我应该如何更改我的代码以便能够用Slider(initWithFrame: CGFrame)初始化Slider?或者从Foo VC设置大小Slider的首选方式是什么?Swift:以编程方式设置VC帧来自另一个VC

// slider.swift

import UIKit 

class Slider: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 
    var collectionView: UICollectionView? 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.minimumLineSpacing = 0 
     layout.sectionInset = UIEdgeInsets.zero 
     layout.itemSize = self.view.frame.size 
     layout.scrollDirection = UICollectionViewScrollDirection.horizontal 

     collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout) 
     collectionView?.dataSource = self 
     collectionView?.delegate = self 
     collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") 
     collectionView?.backgroundColor = UIColor.white 
     collectionView?.isPagingEnabled = true 

     self.view.addSubview(collectionView!) 
    } 

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) 
     cell.backgroundColor = UIColor.red 
     return cell 
    } 
} 

// foo.swift

import UIKit 

class Foo: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     slider = Slider(); 
     slider!.view.frame = CGRect(x: 50, y: 50, width: 20, height: 20) 
     self.view.addSubview(slider!.view) 
     self.addChildViewController(slider!) 
    } 

} 
+0

的一件事是你的*滑块的*尺寸* - 希望它在现实中大得多。对于UICollectionView(以及名称,UISlider),20x20可能太小了。也就是说,你可以为'Slider'编写一个* init(frame:)* - 一个Swift有**总是**使用这个,而不是* init(withFrame:)* - 但你可能想要处理Slider它的子视图布局* viewDidLoadSubviews *覆盖。 – dfd

回答

0

它看起来像你有你的执行的几个问题。虽然它看起来像框架没有改变它实际上是,但你的观点不剪裁到界限,所以看起来框架保持不变。

一些事情要注意。首先,如果您要设置代码并进行布局,则需要在func'viewDidLayoutSubviews'中更新帧/布局。 (看起来像dfd在评论中也提到了这一点)

还要确保你正确地实现了视图控制器遏制。无论何时您尝试将一个视图控制器的视图添加到另一视图控制器的视图中,都应该使用视图控制器包含。下面是该文档的链接为:View Controller Containment Docs Here

据苹果公司应该实施遏制最低如下:(你得到它基本上是正确的,但你的电话是乱序)

func displayContentController(content: UIViewController) { 
    addChildViewController(content) 
    content.view.frame = frameForContentController() 
    view.addSubview(content.view) 
    content.didMoveToParentViewController(self) 
} 

我在下面的示例中包含了一个UIViewController扩展示例。

尝试下面的代码,它是为我工作在一个测试项目:

,在跳出我
import UIKit 


class Slider: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 

var collectionView: UICollectionView? 
var layout : UICollectionViewFlowLayout? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    layout = UICollectionViewFlowLayout() 
    layout?.minimumLineSpacing = 0 
    layout?.sectionInset = UIEdgeInsets.zero 
    layout?.itemSize = view.bounds.size 
    layout?.scrollDirection = UICollectionViewScrollDirection.horizontal 

    collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: layout!) 
    collectionView?.dataSource = self 
    collectionView?.delegate = self 
    collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") 
    collectionView?.backgroundColor = UIColor.blue 
    collectionView?.isPagingEnabled = true 

    self.view.addSubview(collectionView!) 
} 

override func viewDidLayoutSubviews() { 

    // update layout item size here to your new view size 
    layout?.itemSize = view.bounds.size 
    // update collection view frame to new view size here 
    collectionView?.frame = view.bounds 

    super.viewDidLayoutSubviews() 
} 

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) 
    cell.backgroundColor = UIColor.red 
    return cell 
} 
} 


class ViewController: UIViewController { 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let slider = Slider() 

    // note clips to bounds here, avoids confusion as to where the frame is 
    slider.view.clipsToBounds = true 
    addChild(child: slider, frame: CGRect(x: 50, y: 50, width: 30, height: 30)) 
} 


} 


extension UIViewController { 

// MARK: View Controller Containment convenience functions 

func addChild(child:UIViewController, frame:CGRect) { 
    // notify child of containment 
    child.willMove(toParentViewController: self) 

    // add content as child 
    self.addChildViewController(child) 

    // set frame of child content 
    child.view.frame = frame 

    // add childs view to hierarchy 
    self.view.addSubview(child.view) 

    // call containment delegate 
    child.didMove(toParentViewController: self) 
} 

/* 
* Call this function on a child view controller to remove it from it's parent controller and dismiss it. 
*/ 
func remove(fromParentWithAnimationDuration animationDuration:TimeInterval) 
{ 
    // notify child it's being removed 
    self.willMove(toParentViewController: nil) 

    // remove the view 
    self.view.removeFromSuperview() 

    // remove child controller from container 
    self.removeFromParentViewController() 
} 

} 
+0

谢谢!我发现了几个问题,我如何创建其他问题所在的VC。感谢您指出我的错误。关于你的答案,我仍然有几个问题:1)省略自己是否是一种糟糕的做法?就像你在这里所做的那样 - >'view.bounds' 2)为什么你使用'bounds'而不是'frame'? 3)为什么在'func viewDidLayoutSubviews'的末尾放置'super.viewDidLayoutSubviews()'? – Doe

+0

除了在关闭状态下,使用自我并不是必需的。这更多的是个人喜好,我认为它没有所有额外的'自我'就更清洁。 2)这取决于你要做什么。视图框架是它在超视图中的位置,而界限是它在自己的坐标系中的位置。通过使用边界,每次子视图的框架将是0,0,宽度,高度。 3)由于我正在布置视图,因此当我的布局更改完成后,我会调用超级视图。我可能是错的,但是因为它是viewDIDLayoutSubviews,所以在调用super的时候应该放弃所有的视图。 – digitalHound