I love using iCarousel in my swift projects but there is one thing that I could not manage to overcome; I want to use Visual language for layout of the views in my project but whenever I use visual formats for iCarousel, it does not work.
I noticed that the problem is TopMenuCarousel.translatesAutoresizingMaskIntoConstraints=false attribute.
Whenever I disable this attribute, my visual format constraints are disabled for iCarousel, and whenever I enable it, the constraints works perfectly but my iCarousel wont scroll and stay still always.
Current code:
#
import UIKit
import iCarousel
class Step2_HomePage: UIViewController,iCarouselDelegate,iCarouselDataSource {
let TopMenuCarouselCount = 5
var TopMenuCarousel = iCarousel()
override func viewDidLoad() {
super.viewDidLoad()
print("Step2HomePage icinde")
TopMenuCarousel = iCarousel(frame: CGRect())
view.addSubview(TopMenuCarousel)
// TopMenuCarousel.clipsToBounds = true
TopMenuCarousel.type = .Linear
TopMenuCarousel.dataSource = self
TopMenuCarousel.delegate = self
let views = [ "TopMenuCarousel": TopMenuCarousel ]
// 2
var allConstraints = [NSLayoutConstraint]()
let TopMenuCarouselTop = NSLayoutConstraint.constraintsWithVisualFormat(
"V:|-100-[TopMenuCarousel]",
options: [],
metrics: nil,
views: views)
allConstraints += TopMenuCarouselTop
let TopMenuCarouselHorizontal = NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-0-[TopMenuCarousel]-0-|",
options: [],
metrics: nil,
views: views)
allConstraints += TopMenuCarouselHorizontal
TopMenuCarousel.translatesAutoresizingMaskIntoConstraints=false
NSLayoutConstraint.activateConstraints(allConstraints)
// Do any additional setup after loading the view, typically from a nib.
}
func numberOfItemsInCarousel(carousel: iCarousel) -> Int {
print("carousel number")
return TopMenuCarouselCount
}
func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
print("carousel view icinde")
let tempView = UIView(frame: CGRect(x: 0, y: 0 , width: 20, height: 20))
tempView.backgroundColor = UIColor.blueColor()
return tempView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
#
Looks like you're not setting any height to your iCarousel object. Try changing your first Constraint to:
let TopMenuCarouselTop = NSLayoutConstraint.constraintsWithVisualFormat(
"V:|-100-[TopMenuCarousel(20)]",
options: [],
metrics: nil,
views: views)
Here is a full modified version of your original code. I made the views larger (yours were 20x20), and added some color to make it easier to see what's going on.
import UIKit
import iCarousel
class Step2_HomePage: UIViewController,iCarouselDelegate,iCarouselDataSource {
// array of colors to make it easy to see the individual Carousel views
let arrayOfColors = [ UIColor.blueColor(), UIColor.redColor(), UIColor.yellowColor(), UIColor.orangeColor(), UIColor.greenColor()]
let TopMenuCarouselCount = 5
var TopMenuCarousel = iCarousel()
override func viewDidLoad() {
super.viewDidLoad()
print("Step2HomePage icinde")
self.view.backgroundColor = UIColor.lightGrayColor()
// initialize the TopMenuCarousel object
TopMenuCarousel = iCarousel(frame: CGRect())
// add TopMenuCarousel to the view
view.addSubview(TopMenuCarousel)
// if clipsToBounds == true, TopMenuCarousel subviews will be clipped to the TopMenuCarousel frame
// default is false
// TopMenuCarousel.clipsToBounds = true
TopMenuCarousel.type = .Linear
TopMenuCarousel.dataSource = self
TopMenuCarousel.delegate = self
TopMenuCarousel.backgroundColor = UIColor.purpleColor()
let views = [ "TopMenuCarousel": TopMenuCarousel ]
var allConstraints = [NSLayoutConstraint]()
// position TopMenuCarousel 100 from the Top, with a Height of 200
let TopMenuCarouselTop = NSLayoutConstraint.constraintsWithVisualFormat(
"V:|-100-[TopMenuCarousel(200)]",
options: [],
metrics: nil,
views: views)
allConstraints += TopMenuCarouselTop
// set TopMenuCarousel to stretch the full Width of the view
let TopMenuCarouselHorizontal = NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-0-[TopMenuCarousel]-0-|",
options: [],
metrics: nil,
views: views)
allConstraints += TopMenuCarouselHorizontal
// this property *must* be set to false
TopMenuCarousel.translatesAutoresizingMaskIntoConstraints=false
NSLayoutConstraint.activateConstraints(allConstraints)
}
func numberOfItemsInCarousel(carousel: iCarousel) -> Int {
print("carousel number \(TopMenuCarouselCount)")
return TopMenuCarouselCount
}
func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
print("carousel view icinde", index)
// create a 200 x 160 view to add to TopMenuCarousel
let tempView = UIView(frame: CGRect(x: 0, y: 0 , width: 200, height: 160))
// give it one of the colors
tempView.backgroundColor = arrayOfColors[index % arrayOfColors.count]
return tempView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The constraints are created and activated but never added to the view, you should use:
view.addConstraints(allConstraints)
after
NSLayoutConstraint.activateConstraints(allConstraints)
Also as DonMag stated, there is no height constraint, this means that if the iCarousel view doesn't have a correct intrinsic size it won't be displayed and you should add an explicit height like the example DonMag wrote.
Related
I'm working on a project that has a custom segmented control in a UIScrollView. I want to use auto layout to position the segmented control. I'm using this project as my model: https://github.com/honghaoz/UIScrollView-and-AutoLayout
import UIKit
class ViewController: UIViewController {
let scrollView = UIScrollView()
var screenBounds: CGRect { return UIScreen.main.bounds }
override var preferredStatusBarStyle : UIStatusBarStyle {
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
// Setup scroll view
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.backgroundColor = UIColor(red:20/255.0, green:119/255.0, blue:61/255.0, alpha:255/255.0)
view.addSubview(scrollView)
// Setup constraints
var views: [String: UIView] = [
"scrollView": scrollView
]
var constraints = [NSLayoutConstraint]()
// External constraints
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: [], metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView]|", options: [], metrics: nil, views: views)
// Internal constraints
// Note: to let scrollView determines its contentSize, four edges should be explicitly specified
let v1 = newLabelWithText("v1 v1 v1 v1 v1 v1 v1 v1 v1 v1")
scrollView.addSubview(v1)
views["v1"] = v1
//Create Segmented Control
let segmentedB = YSSegmentedControl(
//Set Frame in Callback (Required)
frame: CGRect(x: 0, y: 0, width: 400, height: 60),
titles: [
"Yes",
"No"
],
action: {
control, index in
print ("segmented did pressed \(index)")
})
scrollView.addSubview(segmentedB)
views["v4"] = segmentedB
let v2 = newLabelWithText("v2 v2 v2 v2 v2")
views["v2"] = v2
let v3 = newLabelWithText("v3 v3 v3 v3 v3")
views["v3"] = v3
scrollView.addSubview(v3)
// Horizontal, fully specified
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-200-[v4]-300-|", options: .alignAllLastBaseline, metrics: nil, views: views)
// Vertically, fully specified
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-200-[v3]-1000-|", options: .alignAllLeading, metrics: nil, views: views)
NSLayoutConstraint.activate(constraints)
print("scrollView.contentSize: \(scrollView.contentSize)")
}
}
For some reason, auto layout works just fine with the text labels but not with the segmented control. The callback requires that I input parameters for CGRect, so I simply set the width and height and leave the position parameters at zero. This worked when there was no scrollview, but its not working now.
Also, I'm not using storyboards in this project. All constraints and views are created programmatically.
Any Help appreciated. Thanks
I think you should add this line before adding constraints
segmentedB.translatesAutoresizingMaskIntoConstraints = false
Whenever you add constraints programmatically you should set this property to false in order for constraints to take effect on the view
Hello
I'm trying to put an Image as a background for my ViewControllers, guiding myself for other posts I found this way:
I created the following extension:
extension UIView {
func addBackground() {
// screen width and height:
let width = UIScreen.mainScreen().bounds.size.width
let height = UIScreen.mainScreen().bounds.size.height
let imageViewBackground = UIImageView(frame: CGRectMake(0, 0, width, height))
imageViewBackground.image = UIImage(named: "msa_background")
// you can change the content mode:
imageViewBackground.contentMode = UIViewContentMode.ScaleAspectFill
imageViewBackground.clipsToBounds = true
self.addSubview(imageViewBackground)
self.sendSubviewToBack(imageViewBackground)
}
}
I'm calling this extension in every ViewController with the following code:
override func viewDidLoad() {
super.viewDidLoad()
self.view.addBackground()
}
The problem is when I rotated the screen the image in the background don't fill all the space in the ViewController, I have checked any possible solution that I found but I can't find a way to do it.
I really appreciate any help from you
You are adding the image with the current frame of the screen and never changing it. When you rotate the device it will keep the same frame.
Change it to use AutoLayout like this...
extension UIView {
func addBackground(imageName: String, contentMode: UIViewContentMode) {
let imageViewBackground = UIImageView()
imageViewBackground.image = UIImage(named: imageName)
// you can change the content mode:
imageViewBackground.contentMode = contentMode
imageViewBackground.clipsToBounds = true
imageViewBackground.translatesAutoresizingMaskIntoConstraints = false
self.insertSubview(imageViewBackground, atIndex: 0)
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|[imageViewBackground]|",
options: [],
metrics: nil,
views: ["imageViewBackground", imageViewBackground]))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[imageViewBackground]|",
options: [],
metrics: nil,
views: ["imageViewBackground": imageViewBackground]))
}
}
The auto layout constraints will then make the image view fit to the view no matter how the orientation of the device or frame of the view changes.
My application creates a UITableViewController that contains a custom tableHeaderView which may have an arbitrary height. I've been struggling with a way to set this header dynamically, as it seems the suggested ways have been cutting this header short.
My UITableViewController's relevant code:
import UIKit
import SafariServices
class RedditPostViewController: UITableViewController, NetworkCommunication, SubViewLaunchLinkManager {
//MARK: UITableViewDataSource
var post: PostData?
var tree: CommentTree?
weak var session: Session! = Session.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// Get post info from api
guard let postData = post else { return }
//Configure comment table
self.tableView.registerClass(RedditPostCommentTableViewCell.self, forCellReuseIdentifier: "CommentCell")
let tableHeader = PostView(withPost: postData, inViewController: self)
let size = tableHeader.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize)
let height = size.height
let width = size.width
tableHeader.frame = CGRectMake(0, 0, width, height)
self.tableView.tableHeaderView = tableHeader
session.getRedditPost(postData) { (post) in
self.post = post?.post
self.tree = post?.comments
self.tableView.reloadData()
}
}
}
This results in the following incorrect layout:
If I change the line: tableHeader.frame = CGRectMake(0, 0, width, height) to tableHeader.frame = CGRectMake(0, 0, width, 1000) the tableHeaderView will lay itself out correctly:
I'm not sure what I'm doing incorrectly here. Also, custom UIView class, if this helps:
import UIKit
import Foundation
protocol SubViewLaunchLinkManager: class {
func launchLink(sender: UIButton)
}
class PostView: UIView {
var body: UILabel?
var post: PostData?
var domain: UILabel?
var author: UILabel?
var selfText: UILabel?
var numComments: UILabel?
required init?(coder aDecoder: NSCoder) {
fatalError("Not implemented yet")
}
init(withPost post: PostData, inViewController viewController: SubViewLaunchLinkManager) {
super.init(frame: CGRectZero)
self.post = post
self.backgroundColor = UIColor.lightGrayColor()
let launchLink = UIButton()
launchLink.setImage(UIImage(named: "circle-user-7"), forState: .Normal)
launchLink.addTarget(viewController, action: "launchLink:", forControlEvents: .TouchUpInside)
self.addSubview(launchLink)
selfText = UILabel()
selfText?.backgroundColor = UIColor.whiteColor()
selfText?.numberOfLines = 0
selfText?.lineBreakMode = .ByWordWrapping
selfText!.text = post.selfText
self.addSubview(selfText!)
selfText?.sizeToFit()
//let attributedString = NSAttributedString(string: "Test"/*post.selfTextHtml*/, attributes: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType])
//selfText.attributedText = attributedString
body = UILabel()
body!.text = post.title
body!.numberOfLines = 0
body!.lineBreakMode = .ByWordWrapping
body!.textAlignment = .Justified
self.addSubview(body!)
domain = UILabel()
domain!.text = post.domain
self.addSubview(domain!)
author = UILabel()
author!.text = post.author
self.addSubview(author!)
numComments = UILabel()
numComments!.text = "\(post.numComments)"
self.addSubview(numComments!)
body!.translatesAutoresizingMaskIntoConstraints = false
domain!.translatesAutoresizingMaskIntoConstraints = false
author!.translatesAutoresizingMaskIntoConstraints = false
selfText!.translatesAutoresizingMaskIntoConstraints = false
launchLink.translatesAutoresizingMaskIntoConstraints = false
numComments!.translatesAutoresizingMaskIntoConstraints = false
let views: [String: UIView] = ["body": body!, "domain": domain!, "author": author!, "numComments": numComments!, "launchLink": launchLink, "selfText": selfText!]
//let selfTextSize = selfText?.sizeThatFits((selfText?.frame.size)!)
//print(selfTextSize)
//let metrics = ["selfTextHeight": selfTextSize!.height]
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[body]-[selfText]-[domain]-|", options: [], metrics: nil, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[body]-[selfText]-[author]-|", options: [], metrics: nil, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[body]-[selfText]-[numComments]-|", options: [], metrics: nil, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[launchLink]-[numComments]-|", options: [], metrics: nil, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[body][launchLink]|", options: [], metrics: nil, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[selfText][launchLink]|", options: [], metrics: nil, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[domain][author][numComments][launchLink]|", options: [], metrics: nil, views: views))
}
override func layoutSubviews() {
super.layoutSubviews()
body?.preferredMaxLayoutWidth = body!.bounds.width
}
}
Copied from this post. (Make sure you see it if you're looking for more details)
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let headerView = tableView.tableHeaderView {
let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
var headerFrame = headerView.frame
//Comparison necessary to avoid infinite loop
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
tableView.tableHeaderView = headerView
}
}
}
Determining the header's frame size using
header.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
as suggested in the answers above didn't work for me when my header view consisted of a single multiline label. With the label's line break mode set to wrap, the text just gets cut off:
Instead, what did work for me was using the width of the table view and a height of 0 as the target size:
header.systemLayoutSizeFitting(CGSize(width: tableView.bounds.width, height: 0))
Putting it all together (I prefer to use an extension):
extension UITableView {
func updateHeaderViewHeight() {
if let header = self.tableHeaderView {
let newSize = header.systemLayoutSizeFitting(CGSize(width: self.bounds.width, height: 0))
header.frame.size.height = newSize.height
}
}
}
And call it like so:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
tableView.updateHeaderViewHeight()
}
More condensed version of OP's answer, with the benefit of allowing layout to happen naturally (note this solution uses viewWillLayoutSubviews):
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let header = tableView.tableHeaderView {
let newSize = header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
header.frame.size.height = newSize.height
}
}
Thanks to TravMatth for the original answer.
If you're still having problems with layout with the above code sample, there's a slight chance you disabled translatesAutoresizingMaskIntoConstraints on the custom header view. In that case, you need to set translatesAutoresizingMaskIntoConstraints back to true after you set the header's frame.
Here's the code sample I'm using, and working correctly on iOS 11.
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let headerView = tableView.tableHeaderView else { return }
let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
var headerFrame = headerView.frame
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
tableView.tableHeaderView = headerView
if #available(iOS 9.0, *) {
tableView.layoutIfNeeded()
}
}
headerView.translatesAutoresizingMaskIntoConstraints = true
}
Based on #TravMatth and #NSExceptional's answer:
For Dynamic TableView Header, with multiple line of text(No matter have or not)
My solution is:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let footView = tableView.tableFooterView {
let newSize = footView.systemLayoutSizeFitting(CGSize(width: self.view.bounds.width, height: 0))
if newSize.height != footView.frame.size.height {
footView.frame.size.height = newSize.height
tableView.tableFooterView = footView
}
}
}
tableView.tableFooterView = footView to make sure that your tableview Header or Footer updated.
And if newSize.height != footView.frame.size.height helps you not to be called this method many times
I use the accepted answer for a long time and it always worked for me, until today, when I used a multiple lines label in a complex table header view, I ran into the same issue #frank61003 had:
it create a blank area with multiple lines label.
So in my case, there were big vertical margins around my label. If label text is just 1 line, then everything is fine. This issue only happens when the label has multiple lines of text.
I don't know the exact reason causing this, but I dug for a while and found a workaround to solve the issue, so I want to leave a reference here in case anyone runs into the same problem.
Optional first step, make sure your multiple lines label has the lowest Content Hugging Priority in your table header view, so it can auto increase to fit its text.
Then, add this calculate label height method to your view controller
private func calculateHeightForString(_ string: String) -> CGFloat {
let yourLabelWidth = UIScreen.main.bounds.width - 20
let constraintRect = CGSize(width: yourLabelWidth, height: CGFloat.greatestFiniteMagnitude)
let rect = string.boundingRect(with: constraintRect,
options: .usesLineFragmentOrigin,
// use your label's font
attributes: [.font: descriptionLabel.font!],
context: nil)
return rect.height + 6 // give a little extra arbitrary space (6), remove it if you don't need
}
And use the method above to configure your multiple lines label in viewDidLoad
let description = "Long long long ... text"
descriptionLabel.text = description
// manually calculate multiple lines label height and add a constraint to avoid extra space bug
descriptionLabel.heightAnchor.constraint(equalToConstant: calculateHeightForString(description)).isActive = true
This solved my issue, hope it can work for you too.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let headerView = self.tableView.tableHeaderView {
let headerViewFrame = headerView.frame
let height = headerView.systemLayoutSizeFitting(headerViewFrame.size, withHorizontalFittingPriority: UILayoutPriority.defaultHigh, verticalFittingPriority: UILayoutPriority.defaultLow).height
var headerFrame = headerView.frame
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
self.tableView.tableHeaderView = headerView
}
}
}
Problem in calculating label size when using horizontal or vertical fitting
If all constraint is added, this will work:
headerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
**My Working Solution is:
Add this function in viewcontroller**
public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let headerView = myTableView.tableHeaderView else { return }
let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
var headerFrame = headerView.frame
if height != headerFrame.size.height {
headerFrame.size.height = height
headerView.frame = headerFrame
myTableView.tableHeaderView = headerView
if #available(iOS 9.0, *) {
myTableView.layoutIfNeeded()
}
}
headerView.translatesAutoresizingMaskIntoConstraints = true
}
**Add one line in header's view class.**
override func layoutSubviews() {
super.layoutSubviews()
bookingLabel.preferredMaxLayoutWidth = bookingLabel.bounds.width
}
Just implementing these two UITableView delegate methods worked for me:
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section
{
return 100;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return UITableViewAutomaticDimension;
}
I have a scrollview which contains two containers (UIViews). One UIView contains a UITableView which displays correctly and another ViewController. The viewController has an image which fills it completely. However, when adding the View Controller if I set a background color that shows up.
//
// SideBarViewController.swift
// Sidebar
//
// Created by Satyajit Sarangi on 12/10/15.
// Copyright © 2015 Satyajit Sarangi. All rights reserved.
//
import UIKit
class SideBarViewController: UIViewController {
// MARK: Properties
var scrollView: UIScrollView!
let menuTableView = UITableView()
let sideBarContainerView = UIView()
let mainContainerView = UIView()
let testContainerView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Create a dictionary for the views for the visual format language
let containerViewsDict = Dictionary(dictionaryLiteral: ("sidebar_container", sideBarContainerView), ("main_container", mainContainerView))
// let scrollViewDict = Dictionary(dictionaryLiteral: ("scrollview", scrollView))
// Create two container
// Add the scroll view
scrollView = UIScrollView(frame: view.frame)
// Set Properties for scrollview
scrollView.scrollEnabled = true
scrollView.pagingEnabled = true
scrollView.contentSize = CGSizeMake(view.frame.width, view.frame.height)
// sideBarContainerView.backgroundColor = UIColor.yellowColor()
scrollView.addSubview(sideBarContainerView)
scrollView.addSubview(mainContainerView)
setupMainContainerView()
setupSideBarTableView()
// Add the Scroll View
view.addSubview(scrollView)
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|[sidebar_container]-5-[main_container]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: containerViewsDict)
let scrollview_verticalConstraints1 = NSLayoutConstraint.constraintsWithVisualFormat("V:|[sidebar_container]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: containerViewsDict)
let scrollview_verticalConstraints2 = NSLayoutConstraint.constraintsWithVisualFormat("V:|[main_container]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: containerViewsDict)
sideBarContainerView.translatesAutoresizingMaskIntoConstraints = false
mainContainerView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addConstraints(horizontalConstraints)
scrollView.addConstraints(scrollview_verticalConstraints1)
scrollView.addConstraints(scrollview_verticalConstraints2)
// Add constraints for the Scroll View
// let scrollview_constraint_v = NSLayoutConstraint.constraintsWithVisualFormat("V:|[scrollview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: scrollViewDict)
// let scrollview_constraint_h = NSLayoutConstraint.constraintsWithVisualFormat("H:|[scrollview]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: scrollViewDict)
// scrollView.addConstraints(scrollview_constraint_v)
// scrollView.addConstraints(scrollview_constraint_h)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
view.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height)
scrollView.setContentOffset(CGPoint(x: 100, y: 0), animated: true)
}
// MARK: Set UI Properties
func setupSideBarTableView() {
menuTableView.frame = CGRectMake(0, 0, 200, scrollView.frame.height)
menuTableView.contentSize = CGSizeMake(1000, 1000)
menuTableView.backgroundColor = UIColor.redColor()
sideBarContainerView.addSubview(menuTableView)
let dict = Dictionary(dictionaryLiteral: ("menu_table", menuTableView))
let constraint_h = NSLayoutConstraint.constraintsWithVisualFormat("H:|[menu_table]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict)
let constraint_v = NSLayoutConstraint.constraintsWithVisualFormat("V:|[menu_table]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict)
sideBarContainerView.frame = menuTableView.frame
sideBarContainerView.addConstraints(constraint_h)
sideBarContainerView.addConstraints(constraint_v)
}
func setupMainContainerView() {
// testContainerView.frame = CGRectMake(0, 0, 320, scrollView.frame.height)
// testContainerView.contentSize = CGSizeMake(1000, 1000)
// testContainerView.backgroundColor = UIColor.yellowColor()
let testContainerView = TestViewController()
self.addChildViewController(testContainerView)
mainContainerView.addSubview(testContainerView.view)
// let dict = Dictionary(dictionaryLiteral: ("test_container", testContainerView))
// let constraint_h = NSLayoutConstraint.constraintsWithVisualFormat("H:|[test_container]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict)
// let constraint_v = NSLayoutConstraint.constraintsWithVisualFormat("V:|[test_container]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict)
mainContainerView.frame = testContainerView.view.frame
// mainContainerView.addConstraints(constraint_h)
// mainContainerView.addConstraints(constraint_v)
testContainerView.didMoveToParentViewController(self)
}
}
The view controller looks like this... and the code for it is pasted below. As can be seen, the story board has the image and the viewDidLoad sets it to yellow. However, if I turn off background color, no image is seen.
import UIKit
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor.yellowColor()
}
}
How do I get the TestControllerView to display the views inside it?
You are instantiating the TestViewController like so:
let testContainerView = TestViewController()
That will not use the storyboard. If you want to use the storyboard, you have give that scene a "storyboard id" in Interface Builder, and then you can programmatically to do something like:
let testContainerView = storyboard?.instantiateViewControllerWithIdentifier("TestViewController storyboard id here")
By the way, when you have these sorts of problems, it's useful to run the app from Xcode and then use the view debugger:
That lets you dynamically inspect the view hierarchy (so you can confirm whether something's really missing or just possibly off screen or otherwise not visible).
i have a custom tableCell that working fine, till i am trying to add an image on the left of each cell.
when placing the image inside the conventView all is working fine, but i don't like when the separator is starting in the middle of the image.
and i want to eliminate the space on the left of each row, i want to place my image there, so the cell seperator will show only under the cell content , and not under part of the image, i am strageling this separator for a couple of hours and now i can't show my content..
also my simulator i taking something like 10 sec to show the table content..
can u help me please, i know its suppose to be s simple thing, but i can't manage this to work...
thank you..
here is my custom TableCell
import UIKit
class TableCellMessages: UITableViewCell {
var labUerName = UILabel();
var labMessage = UILabel();
var labTime = UILabel();
var labRead = UILabel();
override func awakeFromNib() {
super.awakeFromNib()
self.imageView.clipsToBounds = true
self.imageView.layer.cornerRadius = 22;
self.imageView.contentMode = UIViewContentMode.ScaleAspectFill
// self.imageView.autoresizingMask = UIViewAutoresizing.None
var currentFont:UIFont = labUerName.font
labUerName.font = UIFont.boldSystemFontOfSize(currentFont.pointSize);
labUerName.setTranslatesAutoresizingMaskIntoConstraints(false)
labMessage.setTranslatesAutoresizingMaskIntoConstraints(false)
labTime.setTranslatesAutoresizingMaskIntoConstraints(false)
labRead.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.addSubview(labUerName)
contentView.addSubview(labMessage)
contentView.addSubview(labTime)
contentView.addSubview(labRead)
//Set layout
var viewsDict = Dictionary <String, UIView>()
viewsDict["username"] = labUerName;
viewsDict["message"] = labMessage;
viewsDict["time"] = labTime;
viewsDict["read"] = labRead;
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[username]-1-[message]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[time]-1-[read]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[username]-[time]-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[message]-[read]-|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
}
override func layoutSubviews() {
super.layoutSubviews()
var x = self.frame.origin.x;
var y = self.frame.origin.y;
var width = self.frame.width;
var height = self.frame.height;
self.imageView.frame = CGRectMake(x, y, height, height);
self.contentView.frame = CGRectMake(x + height, y, width - height , height)
}
}
To fix the cell separator, you'll need to use the separatorInset property on your UITableView which you most likely have a reference to in your view controller:
self.tableView.separatorInset = UIEdgeInsets(0, 0, 0, 0)
See https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/instp/UITableView/separatorInset
Apart from that, you'll save yourself and your fellow programmers a lot of headache if you design your custom cell as a prototype cell in your storyboard instead of laying out your labels etc programmatically.