I have UITableViewController, on top of it I placed an UIView and inside it there is a UICollectionView.
When collectionView data is empty I want to remove the UIView. I tried:
self.collectionView.removeFromSuperview()
and
self.collectionView.hidden = true
These removes the UIView but there is an empty space above my tableview. How can I get rid of it?
Edit: added a photo of my storyboard. Recommended View is not inside the tableviewheader.
It looks like the collection view is a table header view (the way you have positioned it in the storyboard).
Try setting it to nil if data is empty
self.tableView.tableHeaderView = nil
I haven't tried but this code should solve your problem.
self.tableView.tableHeaderView?.isHidden = true
You have placed Recommended View inside the table view - not on top of it. So you could have placed it as header or cell. So when you don't want it to be present, change cell pr header height.
The RecommendedView is a tableHeaderView. Try to have a outlet to the height constraint of the RecommendedView.
Set the height constraint to 0 in case you don't have any element in the collection view.
#IBOutlet var tableHeaderHeighConstraint: NSLayoutConstraint!
override func viewDidLoad(){
if collectionIsEmpty(){
tableHeaderHeighConstraint.constant = 0
self.tableView.tableHeaderView?.layoutIfNeeded()
}
}
Related
I am trying to add a UIView on top of the messagesCollectionView, but the collectionview seems to take up the whole screen making the UIView I want to add unable to be seen. I am looking at their documentation here: https://github.com/MessageKit/MessageKit/blob/master/Sources/Layout/MessagesCollectionViewFlowLayout.swift
My thoughts are to change something in the Layout delegate but I am unsure what and where to change... any thoughts on this would be appreciated!
Thanks!
If you want to have some sort of floating view above the messagesCollectionView, then you can just add it as a subview to the MessagesViewControler's view, just make sure to do it after you've called super.viewDidLoad() because that's where MessageKit adds the collectionView as a subview so if you add it before then, then your view will be behind the collectionView and won't appear. To prevent the cells overlapping with your view, you can use messagesCollectionView.contentInset property to add padding to either the top or bottom if your view is floating there, so that the user can still scroll to all of the messages. Something like this:
override func viewDidLoad() {
super.viewDidLoad()
let subview = UIView()
view.addSubview(subview)
// Either add constraints or set the frame manually
// ...
// Set the contentInset if you want to prevent the messages from overlapping your view
messagesCollectionView.contentInset.top = 10 // For example, if your view was stickied to the top and was height 10px
}
Another route you could go is to have a parent view controller where you add the MessagesViewController as a child VC to the parent, and then size and layout the messagesCollectionView how you want. You can see an example of this in the MessageKit example app, in the MessageContainerController class: https://github.com/MessageKit/MessageKit/blob/master/Example/Sources/View%20Controllers/MessageContainerController.swift
The Collection view cell would need to show and hide additional tools for the device being controlled. The button that collapses would be at the bottom of the UICollectionViewCell. Whenever the button is pressed it would animate downwards revealing the fan or lights extra features or animate upwards when hiding the extra features. I only need help with expanding and collapsing by using the button at the bottom of the cell. An image is attached showing an example.
Add a height constraint for your high/med/low selector.
Connect that constraint to var in your cell class like this:
#IBOutlet weak var checker1HeightConstraint: NSLayoutConstraint!
set that constraint to a value you want (either 0, for hidden, or 50 or 60 if not hidden)
have a method where you set the value:
func toggleControls(visible: Bool)) {
checker1HeightConstraint = visible? 50 : 0
setNeedsLayout()
}
If you are not sure how to set the outlet, just ctrl-drag from the constraint in you storyboard or xib to your custom cellView class. It will give you options to create it.
I want to add button or row end of uitableview. I used tableview footer but its not solution for me. I also tried others way but ı didnt found any result. How can ı pass this problem.
Thanks..
Use UIViewController instead of UITableViewController:
In storyboard add UITableView to your view controller
Create an IBOutlet for UITableView - connect it
Conform your view controller to UITableViewDelegate and UITableViewDataSource
set tableView.delegate = self and tableView.dataSource = self
In storyboard add a button bellow table view and set top button's constraint to be few (e.g. 4) points away from table view's bottom constraint
Create IBOutlet for button and connect it
Add height constraint for your button - set it to 0.0
Set button's title to empty string ("")
Create IBOutlet for button's height constraint and connect it
Check when your table view reaches the end - to check whether your table reached the bottom you can implement tableView:willDisplayCell:forRowAtIndexPath: and check if indexPath.row is the last item in your data source (there are other ways too so you are free to check them)
When your table reached the end - simply set button's title to your desired title with button.setTitle(for) and animate button's constraint to another height (big enough to see the whole button)
When button is pressed you can just do the opposite animation: set button's title to "" and animate height constraint change back to 0.0
How to make a UIStackView re-distribute it's sub-UITableViews while the stackView is inside a scrollview?
My layout hierarchy is based on the official documentation from apple about Dynamic content for StackViews
- UISCrollView
- UIStackView
- UIView A
- UIView B
- UIView C
- UITableView X
- UITableView Y
- UIView D
The constraints are set as documented. The initial layout of the StackView is correct showing all visible subviews. When forcing the regular views to expand beyond the screen's height, scrolling is working as expected. Also when viewing the layout in the storyboard, everything stacks as expected.
At this point the UITableViews are empty. As soon as I add content to the tableView the problem appears.
The problem
When I dynamically update the TableView's by calling .reloadData() on both of them I see their content appearing. (thanks to this answer about non-scrolling tableViews) but the UIStackView is not stacking the UITableViews.
UIView D is stacked below UIView C
UITableView X and UITableView Y also stacked below UIView B
My guess is that I need to invalidate the stackview, or somehow get it to redistribute it's subviews. How can I do this?
First, a warning:
What you're trying to achieve is not really standard iOS behavior. You should first consider a different approach like creating a single grouped table view with multiple sections. You can implement custom views inside your table view as section headers or footers.
Now if you really wanna go with your original approach...
... for some important reason you should be aware that a table view doesn't have an intrinsic content size by default. Thus, you need to tell the table view how tall it should be because otherwise it will only shrink down to a zero height.
You can achieve this by either subclassing UITableView and overriding its intrinsicContentSize() as Rob suggests in this answer to a similar question.
Or you add a height constraint to each of your table views and set their constants dynamically in code. A quick example:
Add both your table views to a vertical stack view in Interface Builder.
Give both table views a leading and a trailing constraint to pin their left and right edges to the stack view.
Create outlets for your table views in the respective view controller:
#IBOutlet weak var tableView1: UITableView!
#IBOutlet weak var tableView2: UITableView!
#IBOutlet weak var tableView1HeightConstraint: NSLayoutConstraint!
#IBOutlet weak var tableView2HeightConstraint: NSLayoutConstraint!
Override the updateViewConstraints() method of that view controller:
override func updateViewConstraints() {
super.updateViewConstraints()
tableView1HeightConstraint.constant = tableView1.contentSize.height
tableView2HeightConstraint.constant = tableView2.contentSize.height
}
Now whenever the content of any of your table views changes (e.g. when you add or remove rows or change the cell contents) you need to tell your view controller that it needs to update its constraints. Let's say you have a button that adds a cell to tableView1 each time you tap it. You might implement its action like this:
#IBAction func buttonTappen(sender: AnyObject) {
// custom method you implement somewhere else in your view controller
addRowToTableView1DataSource()
// reload table view with the updated data source
tableView1.reloadData()
// triggers an updateViewConstraints() call
view.setNeedsUpdateConstraints()
}
tl;dr:
A UITableView isn't intended for use without scrolling enabled and thus you always need to explicitly set its height when its contents change - may it be using constraints or by overriding the table view's intrinsic content size.
I've created a tableview within Viewcontroller and inserted disclosure indicator, but it is not showing, because the right margin is not correct.
What I tried:
selecting table and click in xCode on "pin" button and set left and right to 0, select there all frames in container and clicked: add constraints
but without results.
How can i fix this?
I attached the problem as image. (i have added a frame to focus the problem)
Okay, there can be multiple reasons for which this can happen. For instance, one can forget to deck the cell with wrong identifier or may have set the accessory Indicator in a wrong way. My personal assumption is you probably have set constrain improperly.
So, I am just going to show you the whole process.
Step 1: Drag and UITableView inside your ViewController and drag a UITableViewCell inside that TableView. Select the Table View Cell and assign an identifier. Make sure, in your datasource method, -cellForRowAtIndexPath, you use this same identifier.
Step 2: Go to your View Controller and take an IBOutlet of a UITableView.
#interface MyViewController : UIViewController<UITableViewDataSource>
#property(nonatomic, strong) IBOutlet UITableView *myTableView;
#end
Step 3: Go to the connection Inspector of your storyboard and connect the UITableView with this outlet.
Step 4: Go to the implementation file of your View Controller and populate the datasource methods. Also make sure, you set your TableView's datasource to your view controller.
Now when you build and run this code you won't see the accessory Indicator.
The reason is you didn't set the constraints.
Step 4: Just set the constrains like the following and you are good to go.
This is my final view.
You need to change seperator inset inorder to remove left margin. Its set to default change it to custom and make left insets and right insets to zero. You can set the 'Separator Inset' from the storyboard:
Change Seperator insets to Custom and make left to zero
Try to programmatically set the width and height of the tableView like so...
#IBOutlet weak var resultsTable: UITableView! // connect to tableView
override func viewDidLoad() {
super.viewDidLoad()
let theWidth = view.frame.size.width
let theHeight = view.frame.size.height
resultsTable.frame = CGRectMake(0,0, theWidth, theHeight)
}
The problem was not the margin/layout.
To show disclosure indicator in tableview cell's, it is needed to select disclosure indicator from Accessory menu AND give a identifier for the cell.
Without given identifier the disclosure indicator is not showing.