Adding a UICollectionViewController as a child UIView crashes - ios

I'm trying to add a custom UICollectionViewController in a child UIView and it crashes my app. Is there something wrong with my code or how my CustomCollectionViewController is implemented?
#IBOutlet weak var childView: UIView!
let myCollectionView = CustomCollectionViewController()
//inside viewDidLoad
self.addChildViewController(self.myCollectionView)
self.myCollectionView.didMoveToParentViewController(self)
self.myCollectionView.view.frame = self.childView.bounds<--crashes after executing this line
self.childView.addSubview(self.myCollectionView.view)
self.myCollectionView.delegate = self

This may be a little late, but initialize your CollectionViewController with a layout parameter.
Instead of:
let myCollectionView = CustomCollectionViewController()
use:
let myCollectionView = CustomCollectionViewController.init(collectionViewLayout: UICollectionViewFlowLayout())
That worked for me.

Related

CollectionView doesn't show any CollectionViewCell

I've created a generic UIView class which contains a UICollectionView inside of it. Just as below. (Class Below also handles the protocols of UICollectionView with Default values)
class MyCollectionView: BaseView<CollectionViewModel> {
private lazy var myCollectionView: UICollectionView = {
let temp = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout()) // setting initial collectionView
temp.translatesAutoresizingMaskIntoConstraints = false
temp.delegate = self
temp.dataSource = self
temp.register(CollectionViewCell.self, forCellWithReuseIdentifier: CollectionViewCell.identifier)
temp.clipsToBounds = true
return temp
}()
}
I've created an instance of MyCollectionView(class above), and added as subview to the MainViewController(Class Below). So doing that made me show a MyCollectionView as a subview of MainViewController. I've accomplished so far.
class MainViewController: UIViewController {
private lazy var collectionView: MyCollectionView = {
let temp = MyCollectionView()
temp.translatesAutoresizingMaskIntoConstraints = false
temp.backgroundColor = .black
return temp
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
setUpConstraintsAndViews()
// Do any additional setup after loading the view.
}
Later on I tried to make UICollectionViewCell class and register that to myCollectionView. But still I can not see any cells on my screen. What might I could be missing?
Your MyCollectionView class is not a UICollectionView. It does not have a subview of a UICollectionView it has a private variable myCollectionView that creates a collection view.
As far as I can tell you're adding an instance of MyCollectionView as a subview of your MainViewController. I don't see how that adds a UICollectionView to your view MainViewController.
How is the consumer of your MyCollectionView supposed to get to the collection view that it owns?

Unable to show UILabel after add it to subview

#IBOutlet weak var result: UILabel!
#IBOutlet weak var testview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
testview.layer.shadowColor = UIColor.systemGray.cgColor
testview.layer.shadowOpacity = 0.6
testview.layer.shadowOffset = .zero
testview.layer.shadowRadius = 5
testview.layer.shadowPath = UIBezierPath(rect: testview.bounds).cgPath
testview.layer.shouldRasterize = true
testview.layer.rasterizationScale = UIScreen.main.scale
testview.addSubview(result)
}
After I add result to testview as a subview it's disappeared.
Your Storyboard already added result into the view hierarchy so when you add it again the frame stays the same but the point of reference changes since the superview is now testView so in your case it's going beyond the visible bounds. If you want the UILabel to be a subview of the testView I'd recommend making that change directly on the Storyboard, creating the UILabel programmatically instead of using Storyboards/IBOutlets or updating the frame of the label after adding it to testView.

getting an IBOutlet from another class swift

I have a IBOutlet in a class Main_Screen which is avaliable in a class hooked up to a main ViewController which has a ScrollView but if i try to get it returns nil
code in View Controller
import UIKit
class ViewController: UIViewController , UIScrollViewDelegate {
#IBOutlet weak var scrollVieww: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollVieww.pagingEnabled = true
self.scrollVieww.delegate = self
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let vc = storyboard.instantiateViewControllerWithIdentifier("MainScreen") as? Main_Screen {
// imageview returns nil :(
let imageView = vc.avatarImageView
}
// Do any additional setup after loading the view, typically from a nib.
let V1 = self.storyboard?.instantiateViewControllerWithIdentifier("HomeScreen") as UIViewController!
//Add initialized view to main view and its scroll view and also set bounds
self.addChildViewController(V1)
self.scrollVieww.addSubview(V1.view)
V1.didMoveToParentViewController(self)
V1.view.frame = scrollVieww.bounds
//Initialize using Unique ID for the View
let V2 = self.storyboard?.instantiateViewControllerWithIdentifier("MainScreen") as UIViewController!
//Add initialized view to main view and its scroll view also set bounds
self.addChildViewController(V2)
self.scrollVieww.addSubview(V2.view)
V2.didMoveToParentViewController(self)
V2.view.frame = scrollVieww.bounds
//Create frame for the view and define its urigin point with respect to View 1
var V2Frame: CGRect = V2.view.frame
V2Frame.origin.x = self.view.frame.width
V2.view.frame = V2Frame
//The width is set here as we are dealing with Horizontal Scroll
//The Width is x3 as there are 3 sub views in all
self.scrollVieww.contentSize = CGSizeMake((self.view.frame.width) * 2, (self.view.frame.height))
}
Short answer: Don't do that. You should treat another view controller's views as private.
If you need to manipulate another view controller's UI, add public methods that you use to request the UI change, and then have code inside the VC make the change.
This is both much better design, and it avoids cases where the other view controller's views haven't been created yet, so they're nil and it fails/crashes with an "encountered nil when trying to unwrap optional" message.

UIView Issue in swift2.0

I have created a uiview in storyboard and have placed it in some random point(autoLayout not applied) . Now in viewDidLoad() Im trying to place it at the center of the screen. But its not moving from that place and replaced at center Why? is this because of some order viewController Life Cycle ? But when I Create a UIView programmatically and placed it in center it works .??
class ViewController: UIViewController {
#IBOutlet weak var view1: UIView!
override func viewDidLoad() {
super.viewDidLoad()
view1.center = view.center
}
}
Your guess is correct. You need to do this in viewWillAppear. viewWillLayoutSubviews is also a good place to put this.
use viewDidLayoutSubviews
- (void) viewDidLayoutSubviews {
self.view1.center = self.view.center
}

How to assign a view programmatically in ios

Let me explain my current scenario. I have a ViewController on storyboard as CenterViewController. On that view, I have the following properties-
#IBOutlet weak private var titleLabel: UILabel!
#IBOutlet var actualView: UIView!
I want to assign a view dynamically by program. For that I have a property i.e. -
#IBOutlet var actualView: UIView!
I have created a ViewController in storyboard. Now I need to assign the view that is related to that ViewController something like this-
let newView = ContactsViewController().view
actualView = newView
I know it will not work, but what else can I do for this purpose?
I think this will help you :
let newView = ContactsViewController()
actualView = newView.view

Resources