So I am using a UITableView to display information about different films.
At the top of the VC, I have a UIImage which sits inside of a UIView. And then my table sits underneath. The table currently sits right up against the bottom of the image (which is what I want), see below:
The Issue
I followed a tutorial to add a simple effect, so when the user pulls down on the tableView, the image enlarges. You can see what I mean by seeing the tutorial here: See here
This all worked wonderful and gave my the effect I wanted, however, it's now added an empty space below the image, see the image below:
Everything still works fine, and the effect works as expected, but this space is now there - which I really don't want.
The settings in the storyboard for this VC are set as followed:
The code I added to make the effect is as follows:
private let KTableHeaderHeight: CGFloat = 160.0 // which is the height of my UIImage
var headerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
headerView = tableView.tableHeaderView
tableView.tableHeaderView = nil
tableView.addSubview(headerView)
tableView.contentInset = UIEdgeInsets(top: KTableHeaderHeight, left: 0, bottom: 0, right: 0)
tableView.contentOffset = CGPoint(x: 0, y: -KTableHeaderHeight)
updateHeaderView()
}
And then:
func updateHeaderView() {
var headerRect = CGRect(x: 0, y: -KTableHeaderHeight, width: tableView.bounds.width, height: KTableHeaderHeight)
if tableView.contentOffset.y < -KTableHeaderHeight {
headerRect.origin.y = tableView.contentOffset.y
headerRect.size.height = -tableView.contentOffset.y
}
headerView.frame = headerRect
}
override func scrollViewDidScroll(scrollView: UIScrollView) {
updateHeaderView()
}
If I comment out all the code I've added, it then looks fine again, so I'm guessing it is this code that's causing the space.
I'm really keen to understand why this gap has formed, and how I can remove it, still using the code added to make the image enlarging effect.
Update
My UIImageView layout Attributes:
Your issue is likely the private let KTableHeaderHeight: CGFloat = 160.0 line, which doesn't equal the height of the imageView in the header.
You need to find out the fixed height of the imageView after scaling, which you can get by multiplying the original image height by view width/original image width, and set the imageView height and private var KTableHeaderHeight: CGFloat to that value.
If your using a grouped UITableView then it makes a space for the group, not sure how to get rid of it. You might want to consider making it a plan UITableView and then create the sections headers that you want via the delegate
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
// create UIView here
}
However, after playing with the sample project, it seems like you can adjust your kTableHeightHeader variable in the top to adjust to hide the top section header.
I modified the sample project so you can see it here
Swift code:
tableView.tableFooterView = UIView()
Objective C code:
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
Related
I was wondering how I would go about adding a separator line under each of my table view cells on Xcode (using swift) I want to make it so that under all of the cells other than the first cell it will add a separator.
Thank you in advance :D
Update:
Code that used to work for me.
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let result = UIView()
// recreate insets from existing ones in the table view
let insets = tableView.separatorInset
let width = tableView.bounds.width - insets.left - insets.right
let sepFrame = CGRect(x: insets.left, y: -0.5, width: width, height: 0.5)
// create layer with separator, setting color
let sep = CALayer()
sep.frame = sepFrame
sep.backgroundColor = tableView.separatorColor?.cgColor
result.layer.addSublayer(sep)
return result
}
The code above does the following within the old version however now doesn't add any extra lines.
Example of what I want:
The setup that I have it as:
Add a view on bottom of uitableview cell and hide and unhide when required in cellForRowAt. Use following constraints for seperator view
Add a cell with the same width as the other cells and make the height 1~2 according to your demand after every regular cell.
I would like to have a horizontal scroll layout which displays images. It works fine if setup 0, 0, 0 and 0 the constraints of the UIScrollView. The problem is exactly when I change the constraints to make margins surrounded the UIScrollView. This is what happens:
First image in the UIScrollView
Second image in the UIScrollView
Third image in the UIScrollView
As you can see, each time you scroll, more off-center the current page is.
I have tried to subtract trailing and leading constrains constants to the width of the scrollLayout, play with frames and bouds but without success.
If I run this example in a smaller display like iphone 5S, the problem is more pointed.
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var pageController: UIPageControl!
#IBOutlet weak var scrollView: UIScrollView!
let imagesArray = ["b_1", "b_2", "b_3", "b_4", "b_5"]
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.isPagingEnabled = true
self.pageController.numberOfPages = imagesArray.count
self.pageController.pageIndicatorTintColor = UIColor.blue
self.pageController.currentPageIndicatorTintColor = UIColor.gray
for i in 0...imagesArray.count - 1{
let imageView = UIImageView()
imageView.contentMode = .scaleToFill
imageView.image = UIImage(named: self.imagesArray[i])
let xPos = CGFloat(i)*self.view.bounds.size.width
imageView.frame = CGRect(x: xPos, y: 0, width: view.frame.size.width, height: self.scrollView.frame.size.height )
self.scrollView.contentSize.width = view.frame.size.width*CGFloat(i+1)
self.scrollView.addSubview(imageView)
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let page = scrollView.contentOffset.x/scrollView.frame.width
self.pageController.currentPage = Int(page)
}
}
So, I would like to know how to always obtain the current image centered.
Thank you
EDITED with Rajesh results and view debug:
I would recommend using a UICollectionView in place of a UIScrollView - otherwise you will be building a lot of the basics from scratch. You can use a collection view that centers the images, make sure paging is enabled and you should get the interface you're looking for. Make sure to adopt / conform to the UICollectionViewDelegate & UICollectionViewDelegateFlowLayout protocols with your view controller & set those delegates on your collection view. Hope that helps! Best of luck.
Programmatically i have created a View and added a label and buttons to it. its fine in vertical it aligns to centre but as i rotate the screen it does not aligns to centre rather it seems as left aligned.
This is my code:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 150))
headerView.layer.borderWidth = 1
headerView.layer.borderColor = UIColor.whiteColor().CGColor
headerView.backgroundColor = ClientConfiguration.primaryUIColor()
let myLabel = UILabel()
myLabel.frame = CGRectMake(-1, -1, tableView.frame.width, 30)
myLabel.font = UIFont.boldSystemFontOfSize(14)
myLabel.backgroundColor = ClientConfiguration.primaryUIColor()
myLabel.textColor = UIColor.whiteColor()
myLabel.text = "Select Time Zone"
myLabel.textAlignment = .Center
let frame = CGRectMake(1, 1,headerView.frame.width , 70)
self.btnTimeZone.frame = frame
headerView.addSubview(myLabel)
headerView.addSubview(self.btnTimeZone)
self.buttonTitileString = self.selectedZone.value
self.btnTimeZone.setTitle(buttonTitileString, forState: .Normal)
return headerView
}
In horizontal mode the button text and label are aligned to left
and when i set self.btnTimeZone.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Center
its fine in horizontal mode but in vertical mode they all are right aligned as;
enter image description here
How can i solve this issue i need both of them in centre aligned in both horizontal and vertical mode.
You just need to reload the table when rotate the phone. Implement following method and inside of this method reload the tableView
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
tableView.reloadData()
}
In case of the application should support both portrait and landscape modes, the good approach would be to work with NSLayoutConstraint.
Of course you have both options to create them programmatically or from the Interface Builder, I'd like to note that you are able to create the header view as a cell, without the need of doing it programmatically; That's -obviously- will leads to the ease of setup the desired constrains for the header subviews.
Try this also
change
tableView.frame.width
to
tableView.frame.size.width
You could try to set autoresizing for parent view.
headerView.autoresizesSubviews = true
myLabel.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.btnTimeZone.autoresizingMask = [.flexibleWidth, .flexibleHeight]
In Swift 5 (and 3, 4 too) you got to override viewDidLayoutSubviews() method of life cycle of view controller, it calls after viewWillTransition() method when rotating your device.
In viewDidLayoutSubviews() method you just need to reload the data of your tableView in order to redraw your section header for portrait to landscape or landscape to portrait, and it works perfectly.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.reloadData()
}
Thanks to GayashanK for give me this idea with his answer.
I'm using a UITableViewController with static cells and I want to make it so that the cells do not take up the entirety of the view. I want something more akin to this image: https://i.stack.imgur.com/4nO09.png
I can't quite figure out how to do so. I've been able to change the height thanks to self.tableView.contentInset, but I'm not sure how to change the width.
How would I do this?
EDIT:
Here's my Code for Fay007 as well as an image.
import UIKit
class ContactFormViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Sets the background images
if let patternImage = UIImage(named: "Pattern") {
view.backgroundColor = UIColor(patternImage: patternImage)
}
}
override func viewWillAppear(_ animated: Bool) {
let numberOfRows: CGFloat = CGFloat(self.tableView.numberOfRows(inSection: 0))
let headerHeight: CGFloat = (self.view.frame.size.height - (self.tableView.rowHeight * numberOfRows)) / numberOfRows
self.tableView.contentInset = UIEdgeInsetsMake(headerHeight, 0, -headerHeight, 0)
}
http://imgur.com/a/Q2kfH
The first image I linked has its cells away from the left/right edges, as in my comment I explained I believe they did using autolayout. Since the tableview is a subview of the UIView of the UIViewController, I believe one would be able to assure that. however, when using a UITableViewController, which is required to use static cells in a UITableView, there is no UIView parent.
One easy way of doing this is as follows: In storyboard, or interface builder, add a UIView subview to the UITableviewcell. Create constraints that define your desired distance of this subview to the edges of the cell.
To add rounded corners, you can do so within awakeFromNib by setting the cornerRadius of the subview's layer property to your desired radius.
I'm trying to implement a view very similar to Evernote's screen in which you add a New Note.
It seems like a UITableView embedded in a NavigationController. This tableview contains static cells (2 or 3) with the bottom one being a UITextView in which you add the content of the note, but when you scroll on the textView, the other cells that contain a textField and another control.
How can this be achieved? I know that Apple doesn't recommend a TextView inside a ScrollView, and doing it with table view it gets a bit weird with all the scrolling from the table and text view.
Here are some examples:
Any suggestions?
Thank you!
Firstly, They disabled text view scrolling and set its size to about screen size. Secondly, once text view's text is out of frame, expand it(calculate its size again).
So I found my problem, when I was setting the constraints for the content view (view inside scrollview) I set an Equal value for its height. To fix it I just made that relationship to Greater or Equal than... it now expands.
The other problem now is that when showing the keyboard it is not scrolling to the text I tap to. (The insets are properly setup though)
// MARK: Notififations from the Keyboard
func didShowKeyboard (notification: NSNotification) {
if momentTextView.isFirstResponder() {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.size.height, right: 0)
scrollView.scrollIndicatorInsets = scrollView.contentInset
let caretPosition = momentTextView.caretRectForPosition(momentTextView.selectedTextRange!.start)
let newHeight = caretPosition.height * 1.5
let newCaretPosition = CGRect(x: caretPosition.origin.x, y: caretPosition.origin.y, width: caretPosition.width, height: newHeight)
scrollView.scrollRectToVisible(newCaretPosition, animated: true)
}
}
}
func willHideKeyboard (notification: NSNotification) {
if momentTextView.isFirstResponder() {
scrollView.contentInset = UIEdgeInsetsZero
scrollView.scrollIndicatorInsets = UIEdgeInsetsZero
}
}