Button in the footer of tableview section Swift3 - ios

I have a footer in the section of my tableView.
I try to add a button, in the center, and after to center my button.
I didn't find how I can center my button, I try to use view.center, or give him the width of all the parent view and after use a text align for center my button. (Personally I prefer use the second method .)
Actually my code is this one
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView()
let labelMore = UIButton()
footerView.addSubview(labelMore)
labelMore.sizeToFit()
labelMore.setTitle(footerText(status: "Test"), for: .normal)
labelMore.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
footerView.backgroundColor = #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)
//labelMore.addTarget(self, action:#selector(footerMore(sender:)), for: .touchUpInside)
return footerView
}
And I got, the green square is actually my button, I erase from my code labelMore.frame = footerView.frame, because that don't work
edit: If my question is not clear I want center my button.

None of the code you showed "centers" the button, so it is not surprising that it is not centered. You do not set the frame.origin of labelMore at all, so its origin is zero — the top left corner, exactly as shown in the screen shot.
I erase from my code labelMore.frame = footerView.frame
Yes, well that was never going to work. It's just another case of confusing frame and bounds. Remember, the frame of the subview is in terms of the bounds of the superview. So you would change that code to
labelMore.frame = footerView.bounds
However, that isn't going to work either because footerView has no bounds — you haven't given it any size!
The real solution here is to position labelMore using autolayout. That way, no matter how footerView ends up being sized, labelMore will have the correct position within it. For example, let's assume that you want labelMore to be the same size as footerView:
let footerView = UIView()
let labelMore = UIButton()
footerView.addSubview(labelMore)
labelMore.topAnchor.constraint(equalTo: footerView.topAnchor).isActive = true
labelMore.bottomAnchor.constraint(equalTo: footerView.bottomAnchor).isActive = true
labelMore.leadingAnchor.constraint(equalTo: footerView.leadingAnchor).isActive = true
labelMore.trailingAnchor.constraint(equalTo: footerView.trailingAnchor).isActive = true
labelMore.translatesAutoresizingMaskIntoConstraints = false
// ... and remove the `sizeToFit` ...

Related

Large titles with UITableView and a UIImage as a background

I am making a financial app. I have a UINavigationController, wrapped around the UIViewController. The large titles in the navigation bar are turned on. I am using a UITableView as a scroller, and a UIImageView with a png image as a background. Now as I scroll the UITableView down, I expect the large titles shift to regular titles. By the way, my navigation bar is somewhat transparent. I am not even trying to ask you guys how to fix the transition from the large titles to regular titles in the navigation bar as I am sure that no one knows how to do that. At least none of the fixes that have been proposed here for 7 years could fix it for me. And as I learned here: https://www.reddit.com/r/iOSProgramming/comments/7k60dl/ios11_large_titles_not_shrinking_tip/, whoever is still trying to figure this problem out, should just abandon all hopes. IT IS IMPOSSIBLE TO PLACE UIIMAGEVIEWE BEHIND THE TABLE VIEW AND EXPECT THE LARGE TITLES TRANSITION TO WORK NORMALLY.
Therefore, I pinned the table to the master view and applied the background to the table directly. The transition started working, but very slowly and with hiccups. But that is not the problem. Since I have a transparent navigation bar, I want the background to occupy the entire screen, and the UITableView to be pinned to a safe area from the top, so nothing goes behind the navigation bar.
This is where the conundrum is. If I pin the background image to the table and make the table pinned to a safe area, whenever I scroll down, the large titles shrink, but the background image is stretching like Stretch Armstrong. It looks stupid. But If I pin the table view to the super view, the scrollable content shows through the navigation bar.
Question: How do I pin the table to a safe area, but make the background extend to super view, and have the large titles/regular titles transition still in place? So that the content doesn’t show behind the transparent navigation bar. Here’s my viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(masterTableViewAsViewScroller)
masterTableViewAsViewScroller.delegate = self
masterTableViewAsViewScroller.dataSource = self
let masterTableViewBackground = UIImageView(image: UIImage(named: "moneyBg"))
masterTableViewBackground.frame = self.masterTableViewAsViewScroller.frame
self.masterTableViewAsViewScroller.backgroundView = masterTableViewBackground;
masterTableViewAsViewScroller.pin(to: view)
title = "Some Title"
navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
let image = UIImage.imageFromColor(color: UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.4))
self.navigationController?.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
self.navigationController?.navigationBar.barStyle = .default
}
Also, my extensions, which are placed in a separate swift file:
import UIKit
extension UIView {
func pin(to superView: UIView) {
translatesAutoresizingMaskIntoConstraints = false
topAnchor.constraint(equalTo: superView.topAnchor).isActive = true
leadingAnchor.constraint(equalTo: superView.leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: superView.trailingAnchor).isActive = true
bottomAnchor.constraint(equalTo: superView.bottomAnchor).isActive = true
}
}
extension UIImage{
static func imageFromColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image! } }
By the way, this is a redo for safe area pinning that I am using:
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
masterTableViewBackground.topAnchor.constraint(equalToSystemSpacingBelow: guide.topAnchor, multiplier: 1.0),
guide.bottomAnchor.constraint(equalToSystemSpacingBelow: masterTableViewBackground.bottomAnchor, multiplier: 1.0)
])
} else {
let standardSpacing: CGFloat = 8.0
NSLayoutConstraint.activate([
masterTableViewBackground.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: standardSpacing),
bottomLayoutGuide.topAnchor.constraint(equalTo: masterTableViewBackground.bottomAnchor, constant: standardSpacing)
])
}
I add gifs so you could see what I'm talking about.

UIStackView height, content inside in the middle not at top

I have a UIStackview, and when its filled with a bunch of things, its fine, However, when its filled with 1, or 2 (for example), it spreads them out and not keeps them at top. What did I do wrong?
This is what happens. I want them to be at the top and with No right under it.
for i in 0..<self.itemSpecificsArray.count {
let itemSpecificName = UILabel()
let itemSpecificValue = UILabel()
itemSpecificName.textColor = UIColor(red: 236.0 / 255.0, green: 91.0 / 255.0, blue: 110.0 / 255.0, alpha: 1.0)
itemSpecificName.textAlignment = .left
itemSpecificName.font = UIFont.boldSystemFont(ofSize: 18.0)
itemSpecificValue.textColor = UIColor.black
itemSpecificValue.textAlignment = .left
itemSpecificValue.font = UIFont.systemFont(ofSize: 15.0)
print(self.itemSpecificsArray[i].itemSpecificName)
print("** \(self.itemSpecificsArray[i].itemSpecificValue)")
itemSpecificName.text = self.itemSpecificsArray[i].itemSpecificName
itemSpecificValue.text = self.itemSpecificsArray[i].itemSpecificValue
self.mainSectionItemSpecifics.addArrangedSubview(itemSpecificName)
self.mainSectionItemSpecifics.addArrangedSubview(itemSpecificValue)
if (i == self.itemSpecificsArray.count) {
let view = UIView()
self.mainSectionItemSpecifics.addArrangedSubview(view)
}
}
For each index, it has a itemSpecificName and itemSpecificValue. If I need to put these two Labels inside of a View, then I can do that...That will probably fix it, wouldnt it?
UIStackView wants to stretch its arranged subviews to fill its own (the stack view's) bounds. If you don't want the labels stretched, you either need to change the constraints on the UIStackView so that it can shrink to fit its children, or add an arranged subview to the stack view that can absorb the extract space. For example, you can add a plain UIView with no constraints after the two labels. Auto layout will give the extra space of the stack view's bounds to the UIView.

iOS: Sides of UITableViewCell showing a different color when cell background is changed (Xcode 8, Swift 3)

When implementing a UITableView, I added a background image and set the table view to transparent. However, the sides of the table remain clear even when I change the table view cells to a different color (in order to see the text better), as shown in this image: Table View Cell.
The code I added to get the inner part of the table view:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor(white: 1, alpha: 0.25)
cell.accessoryView?.backgroundColor = UIColor(white: 1, alpha: 0.25)
cell.contentView.backgroundColor = UIColor(white: 1, alpha: 0.25)
cell.tintColor = UIColor(white: 1, alpha: 0.25)
}
And in viewWillAppear:
self.tableView.backgroundColor = UIColor(white: 1, alpha: 0.25)
I'm not sure why the sides don't show up as the same color. I thought it had something to do with the accessory button, but when attempting to change that as well, nothing was changed.
The contentView doesn't cover the whole cell. Try making the setting its background color to the clear color. Then only the cell's background view will show through.
Much of your code is sheer waste; it has nothing to do with the matter. The key lines are:
cell.backgroundColor = UIColor(white: 1, alpha: 0.25)
cell.contentView.backgroundColor = UIColor(white: 1, alpha: 0.25)
That's a silly thing to do, as you are overlaying the cell's translucent background color with another background color (the background color of the content view, which sits in front of the cell).
When you have a problem like this, solve it yourself by making a simpler, clearer test case. For example:
cell.backgroundColor = .red
cell.contentView.backgroundColor = .green
cell.accessoryType = .checkmark
That makes it perfectly obvious what's going on: the green content view partially obscures the red cell. Your code does exactly the same sort of thing.

How to show label outside the collectionView outline

In my CollectionViewCell I am putting a cell, after that I am putting a label on cell.
Now I want to show my label outside the collectionView outline.
Like This
I am set label inside the collection cell Like This
let cell = collectionViewOutlet.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as? CollectionViewCell
cell?.lblDate.text = dateArray[indexPath.row]
if indexPath.item == 9{
cell?.backgroundColor = UIColor(red: 245.0/255.0, green: 112.0/255.0, blue: 108/255.0, alpha: 1.0)
cell?.lblDate.font = UIFont(name: "Helvetica-Bold", size: 30.0)
cell?.clipsToBounds = false
}
But I get Like This
a) Check whether UILabel's superView is set not to clip:
or
superView.clipsToBounds = false
b) Place a view into to the bottom view of each cell, set background color to gray-green and clip its size by another subView. Red cell will not be clipped - the effect remains the same
take your red cell and make transform(CGAffineTransformScale) to make it bigger. Then unselect property clipToBounds of your UICollectionView

Adding a Gradient Background to UITableViewCell Swift

I found this SO question here:
Swift: gradient on a cell of a tableview
I am using a Custom UITableViewCell which has the following code:
public class MyCustomUITableViewCell: UITableViewCell {
override public func layoutSubviews() {
super.layoutSubviews()
//setting backgroundColor works
//self.backgroundColor = UIColor.brownColor()
self.backgroundColor = UIColor.clearColor()
let colorTop = UIColor(red: 192.0/255.0, green: 38.0/255.0, blue: 42.0/255.0, alpha: 1.0).CGColor
let colorBottom = UIColor(red: 35.0/255.0, green: 2.0/255.0, blue: 2.0/255.0, alpha: 1.0).CGColor
let gradient = CAGradientLayer()
gradient.colors = [ colorTop, colorBottom]
gradient.locations = [ 0.0, 1.0]
self.backgroundView = UIView()
//setting view backgroundColor does not work
//self.backgroundView?.backgroundColor = UIColor.redColor()
self.backgroundView!.layer.insertSublayer(gradient, atIndex: 0)
}
}
The UITableViewCells displayed are clear because I set the self.backgroundColor to UIColor.clearColor().
The gradient does not show, and if, instead of adding a gradient to the UITableViewCell.backgroundView,I just set the UITablveViewCell.backgroundView.backgroundColor to UIColor.redColor(), that does not work either.
When I create the UITableViewCell.backgroundView at this line of code:
self.backgroundView = UIView()
I am assuming the backgroundView automatically fills the bounds of the UITableViewCells displayed in the UITableView, in other words, backgroundView is not a 0x0 width x height correct?
This might help you and others: it's the (tiny) UIView subclass I use to draw gradients without having to get into the mess of inserting CALayers. This way UIView handles resizing using things like Auto Layout, which is much easier to work with.
Put this code into a file in your project, then use it as a normal view. It can go straight into your cell's background view if you want. You should be able to customise the colours in code or in IB if you use it that way.
It's trivial code, but please consider it CC-0 licensed – i.e. public domain where possible, "just use it however you want" everywhere else.
#IBDesignable class GradientView: UIView {
#IBInspectable var firstColor: UIColor = UIColor.whiteColor()
#IBInspectable var secondColor: UIColor = UIColor.blackColor()
override class func layerClass() -> AnyClass {
return CAGradientLayer.self
}
override func layoutSubviews() {
(layer as! CAGradientLayer).colors = [firstColor.CGColor, secondColor.CGColor]
}
}
If you're looking for more advanced functionality, try something like SwiftyGradient – it does much the same thing (i.e. pushing the work into a UIView to make things easier), but has more functionality.
As noted in the documentation for UITableViewCell:
If you want to change the background color of a cell, do so in the
tableView:willDisplayCell:forRowAtIndexPath: method of your table view
delegate.
I normally just add another view to my cells that I use as background view, that works in all cases.

Resources