I want to put BlueView under NavigationBar on TableViewController. But it does not work.
like [1]: https://imgur.com/a/5WcQQ
class TableViewController: UITableViewController {
private func setupView() {
view.addSubview(blueView)
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView.snp.makeConstraints { (make) in
make.left.equalTo(view.snp.left)
make.right.equalTo(view.snp.right)
make.top.equalTo(view.safeAreaLayoutGuide.snp.topMargin)
make.height.equalTo(50)
}
}
}
I found that it works by using viewController with tableview.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
private func setupView() {
view.addSubview(blueView)
blueView.translatesAutoresizingMaskIntoConstraints = false
blueView.snp.makeConstraints { (make) in
make.left.equalTo(view.snp.left)
make.right.equalTo(view.snp.right)
make.top.equalTo(view.safeAreaLayoutGuide.snp.topMargin)
make.height.equalTo(50)
}
}
}
But I really want to know why? Or anything else ideas about safeAreaLayoutGuide on UITableViewController.
I think the tableViewController consists of a tableView covering everything, hence you wont be able to place a view in between the tableView and the navigationbar. You can try bringing your blueView on top of the tableView by using view.bringSubview(toFront: blueView)
Secondly your code is a bit off from the best practice.
blueView.snp.makeConstraints { (make) in
make.leading.trailing.top.equalToSuperview()
make.height.equalTo(50)
}
This should have the exact same effect as your code but much shorter.
Edit: If this causes the view to be located below your navigationBar set edgesForExtendedLayout = [] in your viewDidLoad() or setup function
Related
ViewController:
class ViewController: UIViewController, ViewSpecificController {
typealias RootView = CustomView
override func viewDidLoad() {
super.viewDidLoad()
view().configure()
}
override func loadView() { self.view = CustomView() }
}
UIView:
class CustomView: UIView {
func configure() {
backgroundColor = .orange
translatesAutoresizingMaskIntoConstraints = false
addConstraints()
}
func addConstraints() {
var constraints = [NSLayoutConstraint]()
constraints.append(self.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor))
constraints.append(self.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor))
constraints.append(self.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor))
constraints.append(self.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor))
NSLayoutConstraint.activate(constraints)
}
}
Executing this code results in an error "[LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want."
I tried to initialize UIView, the same error appeared there. How to fix it?
From what i can see it looks like your CustomView class is trying to set constraints to itself. The constraints aren't needed as the ViewController will handle sizing it automatically once you replace the original in loadView(). Removing your addConstraints() method from configure() should solve your problem. See if that works...
I am trying to apply the colour picker from the question below.
Simple swift color picker popover (iOS)
The way I set this up was the colour picker class is attached to a UIView within the main view controller. The code by Michael Ros works but when I try to access it using my main view controller nothing happens. Below is the code I use in my view controller. Is this correct? I went over other questions and I am not sure what I am doing wrong.
class ViewController: UIViewController {
weak var colorPickerDelegate: ColorPickerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.colorPickerDelegate = self
}
}
}
extension ViewController: colorPickerDelegate {
func colorChanged(color: UIColor) {
print(color)
}
}
The color picker code can be found on the attached question as I wasn't sure if it was allowed to copy the code over.
Thanks for the help
You should sublcass UIView and assign it to the view controllers view, then set the delegate of the ColorPickerView to the view controller:
ColorPickerView.swift
class ColorPickerView : UIView {
weak var delegate: ColorPickerDelegate?
// Other code from Michael Ros's adaptation.
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
lazy var colorPickerView = ColorPickerView(frame: CGRect(origin: .zero, size: CGSize(width: self.view.frame.width, height: 300)))
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.colorPickerView.delegate = self
self.view.addSubview(colorPickerView)
}
}
extension ViewController: ColorPickerDelegate {
func colorDidChange(color: UIColor) {
print(color)
}
}
you should replace
colorChanged -> colorDidChange !
if you delegate is ColorPickerDelegate; I think so
I created a nib file with a custom collectionViewCell and attached to a viewController
class CustomCollectionView: UICollectionViewCell{}
Now I have to use the exact cell inside a tableView. I created a new nib file and viewController
class CustomTableView: UITableViewCell{}
and I copied the hole code of CustomCollectionView on it. every thing is working fine but I believe that it dose not make sense to copy the hole exact code of CustomCollectionView into CustomTableView and to use the exact same nib file but with a tableViewCell instead of collectionViewCell on it. Is there any way to optimize what I did?
As you said in a comment in suhit's answer, you can do this by using a common view in both the CollectionViewCell and TableViewCell subclasses. You don't need a ViewController since it adds extra overhead. A simple UIView is enough. Some code to show what I mean:
class CustomTableViewCell: UITableViewCell {
var customView: CustomView!
func awakeFromNib() {
super.awakeFromNib()
customView = CustomView()
customView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(customView)
customView.fillSuperview()
}
}
class CustomCollectionViewCell: UICollectionViewCell {
var customView: CustomView!
func awakeFromNib() {
super.awakeFromNib()
customView = CustomView()
customView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(customView)
customView.fillSuperview()
}
}
extension UIView {
func fillSuperview() {
guard let superview = superview else {
return print("no superview")
}
topAnchor.constraint(equalTo: superview.topAnchor).isActive = true
bottomAnchor.constraint(equalTo: superview.bottomAnchor).isActive = true
leftAnchor.constraint(equalTo: superview.leftAnchor).isActive = true
rightAnchor.constraint(equalTo: contentVisuperviewew.rightAnchor).isActive = true
}
}
A sample implementation for the CustomView class:
class CustomView: UIView {
func initialize() {
//...
}
override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
}
}
If you wish to create your custom view in a xib that's also fine, but it's a little trickier. This is beyond the scope of the question but I'm just going to leave a link here in case you need it.
If you want to use same view then its better to use similar type view i.e. use collectionView at both places so that you can use the CustomCollectionViewCell in both ViewControllers. UICollectionView is highly customisable so you can do whatever you want to do with UITableView in UICollectionView as well.
I have a parent view controller that acts as a container for a UIPageViewControllerand another UIViewController (called commentsViewController). I want to show the inputAccessoryView inside the commentsViewController however it doesn't seem to be working. I have added the commentsViewController to the parent like so:
commentsViewController = storyboard!.instantiateViewControllerWithIdentifier("CommentsViewController")! as! CommentsViewController
self.addChildViewController(commentsViewController)
self.view.addSubview(commentsViewController.view)
//...I have set some autolayout constraints here
commentsViewController.didMoveToParentViewController(self)
Then inside CommentsViewController, I have the following:
#IBOutlet var customView: UIView!
override var inputAccessoryView: UIView {
return customView
}
override func canBecomeFirstResponder() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
self.becomeFirstResponder()
}
Unfortunately this doesn't work and the inputAccessoryView is not displayed... Can anyone see what I'm missing?
Thank you.
Turns out that because I was animating the view, becomeFirstResponder() automatically returned false. After the animation it works fine.
I have created common sidemenu for all main view controller using reference https://github.com/evnaz/ENSwiftSideMenu
Now the issue is i have created sidemenu view controller from storyboard instead of using code itself,it will not show anything on side menu.
Ideally it has to show the page which design from story board.
Actually only TableViewController work with this example. i need to work with UIViewController.
Anyone have idea about this ?
Check out the latest version, I added precisely that functionality a few weeks ago: you can now use a UIViewController, no need to use a UITableViewController.
But other than that, I can't tell without more information why it doesn't show up.
I'm using it in several apps and it works ok.
I've got a UINavigationController, which uses a subclass of ENSideMenuNavigationController, and a UIViewController for the menu itself.
This is it, basically:
class MainNavigationController: ENSideMenuNavigationController, ENSideMenuDelegate {
override func viewDidLoad() {
super.viewDidLoad()
var mainMenuViewController: MainMenuViewController = storyboard?.instantiateViewControllerWithIdentifier("MainMenuViewController") as! MainMenuViewController
mainMenuViewController.navController = self
sideMenu = ENSideMenu(sourceView: self.view, menuViewController: mainMenuViewController, menuPosition:.Right)
//sideMenu?.delegate = self //optional
sideMenu?.menuWidth = 240.0 // optional, default is 160
sideMenu?.bouncingEnabled = false
sideMenu?.animationDuration = 0.2
// make navigation bar showing over side menu
view.bringSubviewToFront(navigationBar)
}
// MARK: - ENSideMenu Delegate
func sideMenuWillOpen() {
println("sideMenuWillOpen")
}
func sideMenuWillClose() {
println("sideMenuWillClose")
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
super.didRotateFromInterfaceOrientation( fromInterfaceOrientation )
sideMenu?.updateFrame()
}
}
Then I have the menu view itself, also in the Storyboard, which is a UIViewController. Here is a fragment:
class ERAMainMenuViewController: UIViewController {
weak var navController: ERAMainNavigationController?
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var exitButton: UIButton!
#IBOutlet weak var headImage: UIImageView!
let kInset:CGFloat = 64.0
override func viewDidLoad() {
super.viewDidLoad()
// Customize apperance of table view
tableView.contentInset = UIEdgeInsetsMake(kInset, 0, 0, 0) //
tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
tableView.backgroundColor = ERAssistantTheme.sideMenuItemBackgroundColor
tableView.scrollsToTop = false
// Preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = true
// tableView.selectRowAtIndexPath(NSIndexPath(forRow: selectedMenuItem, inSection: 0), animated: false, scrollPosition: .Middle)
}
}