UITableViewCells bleeding off bottom and disappearing - swift

My tableview cells are only showing 3 out of 4 in my last section. Decreasing their height, more appear. Increasing the row height, less appear.
My height for row at index path:
return 64
and my tableview is created:
lazy var performanceTableView: UITableView = {
let tableView = UITableView()
tableView.dataSource = self
tableView.delegate = self
tableView.frame = self.view.bounds
tableView.separatorStyle = .None
tableView.scrollEnabled = true
tableView.backgroundColor = UIColor.backgroundColor()
tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.backgroundView = nil
return tableView
}()
my tableview cells seem to stop at the bottom, like my view height is limited, stuck to a frame.. any idea why?

UITableView clipsToBounds property is set to true by default. You may want to change that if you're looking for the cells to continue through the bottom of the view's frame.
Additionally, set the tableview's frame to the view's frame, or create constraints to bind this view to the edges.

Related

UIStackView and a placeholder view in another UIStackView problem

There is a problem if you have a UIStackView(testStack) and a placeholder UIView(testView) inside another UIStackView(mainStack). It is meant that if there is no content in the testStack it will collapse, and the testView will take all the space. There is even a content hugging priority set to maximum for the testStack so it should collapse its height to 0 when there are no subviews. But it does not. How to make it collapse when there is no content?
PS If there are items in the testStack, everything works as expected: testView takes all available space, testStack takes only the space to fit its subviews.
class AView: UIView {
lazy var mainStack: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.backgroundColor = .gray
stack.addArrangedSubview(self.testStack)
stack.addArrangedSubview(self.testView)
return stack
}()
let testStack: UIStackView = {
let stack = UIStackView()
stack.backgroundColor = .blue
stack.setContentHuggingPriority(.init(1000), for: .vertical)
return stack
}()
let testView: UIView = {
let view = UIView()
view.backgroundColor = .red
return view
}()
init() {
super.init(frame: .zero)
backgroundColor = .yellow
addSubview(mainStack)
mainStack.translatesAutoresizingMaskIntoConstraints = false
mainStack.topAnchor.constraint(equalTo: topAnchor).isActive = true
mainStack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
mainStack.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
mainStack.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
When auto-layout arranges subviews in a UIStackView, it looks at:
the stack view's .distribution property
the subviews' height constraints (if given)
the subviews' Intrinsic Content Size
Since you have not specified a .distribution property, mainStack is using the default of .fill.
A UIStackView has NO Intrinsic Content Size, so auto-layout says "testStack has a height of Zero"
A UIView has NO Intrinsic Content Size, so auto-layout says "testView has a height of Zero"
Since the distribution is fill, auto-layout effectively says: "the heights of the arranged subviews are ambiguous, so let's give the last subview a height of Zero, and fill mainStack with the first subview.
Setting .setContentHuggingPriority will have no effect, because there is no intrinsic height to "hug."
If you set mainStack's .distribution = .fillEqually, you will get (as expected) testStack filling the top half, and testView filling the bottom half.
If you set mainStack's .distribution = .fillProportionally, you will get the same result... testStack filling the top half, and testView filling the bottom half, because .fillProportionally uses the arranged subviews' Intrinsic Content Sizes... in this case, they are both Zero, so "proportional" will be equal.
If you set mainStack's .distribution = .equalSpacing or .distribution = .equalCentering, you won't see either testStack or testView ... auto-layout will give each of them a height of Zero, and fill the rest of mainStack with (empty) "spacing."
If your goal is to have testStack "disappear" if it is empty, you can either:
set it hidden, or
subclass it and give it an intrinsic height

How to programmatically set the constraints of the subViews of a UIPageViewController?

I have contained the subViews of a UIPageViewController within a UIView so that my screen has a partial scrollView container. However, the subViewControllers extend beyond both, the UIView that is supposed to contain the (horizontal/swiping page style) scrollView and the screen of the device.
I have already tried to use autolayout constraints but the subViews still go beyond the device screen.
Here is the UIView that contains the subViews of the UIPVC:
let pagingContainer: UIView = {
let view = UIView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
and here is the set up within viewDidLoad():
let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
addChild(pageController)
pageController.didMove(toParent: self)
pagingContainer.addSubview(pageController.view)
In case I haven't articulated properly:
What I wish for to happen is that the bottom half of my screen is a horizontal-page-style swiping scrollView that contains x number of subViewControllers (under UIPVC), and the size of subViewControllers are limited to the size of the UIView(pagingContainer).
I think I might understand what you're asking.
It should be pretty simple, set your left/right/top/bottom constraints for the pageController.view to be equal to the pagingContainer
In my example, I'm using SnapKit, so I set the edges equal to superview (which is the paingContainer).
let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
self.addChild(pageController)
pageController.didMove(toParent: self)
pagingContainer.addSubview(pageController.view)
// I set up constraints with SnapKit (since I mostly use that pod)
pageController.view.snp.makeConstraints({ (make) in
make.edges.equalToSuperview()
})
// But if I remember correctly, you can also set it like so:
pageController.view.translatesAutoresizingMaskIntoConstraints = false
pageController.view.widthAnchor.constraint(equalTo: self.pagingContainer.widthAnchor).isActive = true
pageController.view.heightAnchor.constraint(equalTo: self.pagingContainer.heightAnchor).isActive = true
pageController.view.centerXAnchor.constraint(equalTo: self.pagingContainer.centerXAnchor).isActive = true
Here is a quick gif of what it looks like. Main view controller only has red background and a pagingContainer on the bottom half and inset of 30 on each side (to demonstrate the size of pageController being within the pagingContainer and not overflowing)

Snapkit centerY constraint centers item above the center Y axis

I'm trying to make a custom UICollectionView cell class. The cell consists of a content view and a label. I want the label to be in the center of the view, horizontally and vertically, but instead the label is placed above the content view's center y axis.
I've made sure that the constraints are set, no other constraints are being set, and that the issue affects all views in the content view (I added another view and set its center Y axis as a test, and that also didn't work). I also set the content view and the label's background colors to be contrasting, and have confirmed that the label is not lying on the content view's center y anchor.
Here is how I set the consraints:
label.snp.makeConstraints{make in
make.centerX.centerY.equalToSuperview()
}
Here is what I get instead. Clearly the label is not centered vertically. You can see the blue UIView, which I added as a test, is also not centered vertically.
I used to add my constraints programmatically in this way
self.view.addSubview(image)
image.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
image.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
image.heightAnchor.constraint(equalToConstant: 30).isActive = true
image.widthAnchor.constraint(equalToConstant: 30).isActive = true
and my image is declarated in this way
let image: UIImageView = {
let theImageView = UIImageView()
theImageView.image = UIImage(named: "ico_return")
theImageView.translatesAutoresizingMaskIntoConstraints = false
return theImageView
}()
Hope it helps
Can you try Following Code.
class FilterCollectionViewCell: UICollectionViewCell {
let labelTemp = UILabel()
override func awakeFromNib() {
labelTemp.backgroundColor = .white
labelTemp.textColor = .black
labelTemp.text = "testing"
self.contentView.addSubview(labelTemp)
labelTemp.snp.makeConstraints { (make) in
make.centerX.centerY.equalTo(self.contentView)
}
}
}
Fast and easy:
myLabel.snp.makeConstraints { (make) in
make.center.equalTo(self.topView.snp.center)
}

UITableview cell ignores constrains

I have set a fixed width for a UIButton inside of a cell, which is inside of a UITableView. When changing text programmatically in the UIButton,the UIButton is starting to resize. When I am changing text in the Storyboard, the UIButton's width stays the size I told him to be (not changing). Why does the UIButton is resizing when changing text programmatically? I do not want this to happen. Thanks.
00:00 is a UILabel, 100 + 1000 & 500 is the UIButton, which should have a fixed width.
Code:
freeCoinsArray.append(freeCoinsClass(freeCoinsImage: "Coin", freeCoinsDescription: "Free coins", getFreeCoins: "100 + 1000", freeCoinsCountdown: "00:00"))
Cell for row at function:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! FreeCoinsTableViewCell
cell.imageForFreeCoins.image = UIImage(named: freeCoinsArray[(indexPath as NSIndexPath).row].freeCoinsImage!)
cell.descriptionFreeCoins.text = freeCoinsArray[(indexPath as NSIndexPath).row].freeCoinsDescription
cell.getFreeCoinsButton.setTitle(freeCoinsArray[(indexPath as NSIndexPath).row].getFreeCoins, for: .normal)
cell.countDown.text = freeCoinsArray[(indexPath as NSIndexPath).row].freeCoinsCountdown
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
return cell
However I now see that the UITableView is ignoring more constrains. I also have a image view with a proportional height of 0.3 of the row, but it is scaled to 1.0 of the row's height. see:
How it should be:
How it is:

Animate Layout Changes inside UICollectionViewCell and it's subviews having AutoLayout constraints

I'm increasing/decreasing the size of a collection view cell upon selection. The cell has subviews including a green bar, a the label "vs" and two numeric text fields. As shown on the gif/link below. The challenge is to animate the scale and also animate the subviews scale contained within the cell and maintain the layout constraints given. What is happening as shown on the video, is that the target layout jumps to it's final destination without animating the changes. On initial click, the cell "5vs0" scales nicely but the "0" textfield jumps to the far right without any animation. On second click to minimise the scale, the green bar on the left immediately resize to value equal to the textfields 5 and 0. This means that the auto layout constraints are working well with the container view (collection view cell) when it scales! The only problem is that the layout constraints do not animate along with the collection view's invalidate layout.
Video showing collection view cell scale but unintended subview jerky changes
I've set up the xib file with no auto layout warnings or errors. The collection view's layout get invalidated upon cell click, and a call to setCollectionViewLayout with animation set to true. NB after which I call a central dispatch to the main queue to call layoutIfNeeded against the collection view cell that needs changing. This doesn't seem to affect the layout animation on the subviews. Structure wise, as written on the code below, I keep a dictionary of layouts to which I toggle in between selecting a cell item.
I could manually invoke animation blocks to change the bounds of the subviews, however this is rather messy against different iOS screen sizes etc.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
var cell = collectionView.cellForItemAtIndexPath(indexPath) as! MatchEntryCell
if (collectionView.collectionViewLayout.isEqual(self.layouts[.Standard]!)){
collectionView.setCollectionViewLayout(self.layouts[.Edit]!, animated: true)
cell.homeScore!.userInteractionEnabled = true
cell.homeScore!.becomeFirstResponder()
picker.selectRow(cell.homeScore!.text.toInt()! , inComponent: 0, animated: true)
picker.selectRow(cell.awayScore!.text.toInt()! , inComponent: 1, animated: true)
} else if (collectionView.collectionViewLayout.isEqual(self.layouts[.Edit]!)) {
collectionView.setCollectionViewLayout(self.layouts[.Standard]!, animated: true)
cell.homeScore!.resignFirstResponder()
cell.homeScore!.userInteractionEnabled = false
}
dispatch_async(dispatch_get_main_queue()) {
UIView.animateWithDuration(0.5, animations: { () -> Void in
cell.layoutIfNeeded()
})
}
}
I've added autoresizing masks with width and height as well as below for the subviews on my UICollectionViewCell subclass. But no joy! This post is related to this solution, but I have no joy! Autolayout is not resizing Uicollectionviewcell items when animating between layouts
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.borderWidth = 1
self.layer.cornerRadius = 10
self.layer.borderColor = UIColor.clearColor().CGColor
self.homeBar?.autoresizingMask = .FlexibleWidth | .FlexibleHeight
self.homeScore?.autoresizingMask = .FlexibleWidth | .FlexibleHeight
self.awayBar?.autoresizingMask = .FlexibleWidth | .FlexibleHeight
self.awayScore?.autoresizingMask = .FlexibleWidth | .FlexibleHeight
self.autoresizingMask = .FlexibleWidth | .FlexibleHeight
}
Anyone have any ideas or suggestions? Cheers!
I've solved this problem by using legacy springs and struts. The alignment rects don't interpolate the collection view cell's itemSize change when using auto layout, but springs and struts does.