ios scrollview with a full screen video as main content - ios

this is the layout i want to acheive
I am trying to figure out how to make this layout work on different screens. i have tried to get the screen height and programatically set the video layer height equal to it. The volume button constrains are 25 from the right margin and 25 from the bottom of the video. The problem is that when i try to run the app the volume button shows in the middle right of the screen instead on the right of the bottom corner. Also the image views are overlapping the video instead of showing up under it. My assumption is that the constrains of these elements see the height of the video layer in the story board, not the height that i set programatically in the ViewController.swift.

You can achieve a more coherent layout with a table view and having a section for your full screen video and the rest of the image views in another section. The section for your video will have UIScreen.main.bounds.height for the cell height so that you can have a dynamic full screen height regardless of the device.
class ViewController: UITableViewController {
var arr: [[String]] = {
var arr = [[String]]()
arr.append(["Video"])
var imageArr = [String]()
for index in 1...20 {
imageArr.append(String(index))
}
arr.append(imageArr)
return arr
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return arr.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = arr[indexPath.section][indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 {
return UIScreen.main.bounds.height
} else {
return 100
}
}
}
As for the volume button, you can create a custom cell for the video section and load it in the cellForRowAt method. Make sure you're using Autolayout and not CGRect to position it.

first of all you are working with ScrollView so you need to give each item in you screen a height so you will give the video screen height "Fixed Height" then you will give your button a fixed height as well and connect it from trailing, leading, bottom and Top and I think it will work with you, and if there is any issue appeared feel free to comment with it

Related

How to narrow UITableView cell height if there is dynamic structure in Swift?

I have a tableView and cells. The Cells are loaded from a xib and they have a label with automatic height. I need to narrow one cell if the user taps on it.
I have tried hiding - doesn't work
I have tried removeFromSuperView()- doesn't work
Is there any alternative?
When setting up your tableViewCell store the height anchor you want to update
var yourLabelHeightAnchor: NSLayoutConstraint?
private func setupLayout() {
yourLabelHeightAnchor = yourLabel.heightAnchor.constraint(equalToConstant: 50)
// Deactivate your height anchor as you want first the content to determine the height
yourLabelHeightAnchor?.isActive = false
}
When the user clicks on a cell, notify the tableView that the cell is going to change, and activate the height anchor of your cell.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "YourTableViewCellIdentifier") as? YourCell
self.tableView.beginUpdates()
cell?.yourLabelHeightAnchor?.isActive = true
self.tableView.endUpdates()
}
Did you try to do something like this:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var result: CGFloat
if (indexPath.row==0) {
result = 50 }
else {result = 130}
return result
}
This is just an example where height is changed for the first row. I tested on my application and it gave result like this.

Tableview rounded corner not showing up in bottom

I am using corner radius to set rounded border of UITableView, Following is my code
self.tableView.layer.cornerRadius = 8.0
self.tableView.layer.masksToBounds = true
But its showing like this without rounded corner in bottom :(
If your table height is proper then, your second cell inner view's height is greater that its height.
Try removing your inner view from cell or if there is no inner view then check your tableview height.
Thanks.
I set up a quick demo project with a sample viewcontroller containing the following code:
#IBOutlet var tableView: UITableView! {
didSet {
tableView.rowHeight = 44
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 }
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath)
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.layer.cornerRadius = 10
}
In storyboard the viewcontroller looks like this:
As you can see the tableview has a fixed height of 128pt. Although the tableview contains only two rows with a height of 44pt each (88pt in total) the tableview's corners look fine. So there has to be some other issue in your code.

Swift UIView Border adjusts after UITableView scrolling

I have a problem with my UITableView sections (and their height, I guess).
Within a section header, I have a view (named cornerRadiusView) within which there are few labels. These labels have dynamic content (fetched from a REST service). So whenever a UILabel height is increased, I am increasing the height of the cornerRadiusView to properly accommodate the content.
The problem is, all this works as expected only when I scroll my tableView. Till then, the heights are improper.
Here I am posting GIF to show what's going on.
I can give more details and code as needed. Could someone please look at where there is a problem?
You can use below functions
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
And reload table view in below method
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableview.reloadData()
}
And if you are maintaining dynamic height then manage those height in cell
override func layoutSubviews()
{
}

Self-Sizing Table View Cell in Xcode 9

I have a UITableViewController where the cell's self sized correctly using Xcode 8 and Swift 3. Now that I'm using Xcode 9 and Swift 4, they aren't expanding and are just using the default height of 44.
(I have about a sentence or two in each UITableViewCell)
I was using this before:
// MARK: - Table view delegate
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
... but was able to comment it out because per Updating Your App for iOS 11 said that the default would be self-sizing now:
I've tried playing around with changing the deployment target to iOS 11, playing around in Storyboard (but I'm using a Table View Cell style Basic so there is not much AutoLayout to be done), and I can't figure out what is going on.
I have the UILabel title set to 0 Lines, and have Line Break Word Wrap, but still not getting anywhere close to getting the cell to expand based on the text content inside of it in Xcode 9. Any ideas?
Thanks!
Edit:
Here's the options (that I don't have) for pinning since it is a Basic cell:
I had the same problem and solved it with to lines of code:
class MyTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
}
Maybe it is a bug in Xcode.
Update
New in Xcode 9 beta 3:
Interface Builder now supports setting the estimatedRowHeight of UITableView. This allows self-sizing table cells by setting the estimated height to a value other than zero, and is on by default. (17995201)
I had the same broken table view issue. Fix was just one click.
Go to your xib or storyboard scenes with table views, go to the size inspector, and you'll see the table view heights (even on dynamic table views) as 44, and sections will be 22. Just click "automatic" and boom, it will present as expected.
Note that I also specify the following in viewDidLoad of the UITableViewController subclass (layoutSubviews solves issues with the first load of a tableViewController not positioning correctly in relation to a non-translucent navBar).
self.tableView.estimatedRowHeight = 180;
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.tableView layoutSubviews];
In addition to
tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
you should set a height constraint for the contentView of the tabeleViewCell.
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let height: CGFloat = 200
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
I got the same issue and I read about it in many documentation, satisfying answer was something like this, You have to check both options in order to get proper height, because estimated height is needed for initial UI setup like scrollview bars and other such stuff.
Providing a nonnegative estimate of the height of rows can improve the performance of loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.
When you create a self-sizing table view cell, you need to set this property and use constraints to define the cell’s size.
The default value is 0, which means there is no estimate. (Apple Documentation)>
see this image for storyboard
Also note that there is a bug in xCode 9, when you try to apply Lazy loading in automatic height calculation, it will scroll unexpectedly, so I'll recommend you to use programmatic way in this regard.
self.postTableView.estimatedRowHeight = 200;
self.postTableView.rowHeight = UITableViewAutomaticDimension;
something Like this. Thanks!
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tblview: UITableView!
var selectindex = -1
var arrnumber = ["1","2","3","4","5"]
var image = ["index.jpg","rose-blue-flower-rose-blooms-67636.jpeg","index.jpg","rose-blue-flower-rose-blooms-67636.jpeg","index.jpg"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrnumber.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)as! ExpandableTableViewCell
cell.lblnumber.text = arrnumber[indexPath.row]
cell.img.image = UIImage(named: image[indexPath.row] as! String)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if (selectindex == indexPath.row)
{
return 250
}
else{
return 60
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if(selectindex == indexPath.row)
{
selectindex = -1
}else{
selectindex = indexPath.row
}
self.tblview.beginUpdates()
self.tblview.endUpdates()
}
}
For me, Safe Area was checked. Unchecking "Safe Area" did the work for me.

UITableViewWrapperView size is not changing as per the content if row height is UITableViewAutomaticDimension

UITableViewWrapperView size is not changing as per the content if row height is UITableViewAutomaticDimension.
I am trying to create a Feed listing with TableView and dynamic height rows.
TableView is scrollable but UITableViewWrapperView looks like it's not changing its size!
Below is the code and screenshot of the view hierarchy.
I think its strange.
Code:
class FeedController: UITableViewController {
var items: NSMutableArray = []
override func viewDidLoad() {
super.viewDidLoad()
refreshControl?.addTarget(self, action: "feedLoad", forControlEvents: UIControlEvents.ValueChanged)
self.feedLoad()
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 120.0
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
println("called")
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return self.getCellForItemAtIndexPath( indexPath )
}
func getCellForItemAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell {
let item: Dictionary = self.items[indexPath.row] as Dictionary<String, AnyObject>
let cell = tableView.dequeueReusableCellWithIdentifier( (item["type"] as String) + "Cell", forIndexPath: indexPath ) as FeedViewCell
cell.fillData(item)
return cell as UITableViewCell
}
func feedLoaded(){
tableView.reloadData()
}
func feedLoad(){
// Feed Load Logic which will call next line once feed loaded
self.feedLoaded()
}
}
I am assuming you have auto layout configured for your cell, as that's the only way to get this working. Auto Layout should be able to calculate the height based on your cell constraints.
So you should have constraints between your views vertically and between the views on the top and bottom edges the super view (in this case the cell view).
Suppose you have a cell with title and description, like this:
|------------------|
| Title |
| |
| Description with |
| long multiple |
| lines of text |
|------------------|
In this example you have to set add a constraint with a vertical space between title and description, a constraint of vertical space between the title's top and the cell view top and a vertical space between the description's bottom and the cell view's bottom.
The documentation for estimatedHeightForRowAtIndexPath() says that the value retuned by that call is the placeholder value for all till a scroll event occurs. I am guessing that when the scroll even does occur, heightForRowAtIndexPath will get called. So:
Change the value for estimated height and see if that is the fixed
height that you observe.
Does heightForRow get called when you scroll? If not, may be there are other issues about scrolling, such as contentSize etc., that need addressing so that scrolling does take place.
When you using automaticDimention, You should add constraints to both sides of UILabels in UItableViewCell.

Resources