How to add a 10px space around a tableViewCell? - ios

I'm trying to create a tableViewCell with a 10px spacing around it so the cell doesn't touch the edges of the screen. I tried doing something like this I saw on another stackOverflow post in my cellForRowAtIndexPath but all I got was a black screen once I ran it in simulator:
cell.contentView.backgroundColor = UIColor.white
let whiteRoundedView : UIView = UIView(frame: CGRect(x: 10, y: 10, width: self.view.frame.size.width - 20, height: 188))
whiteRoundedView.layer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [1.0, 1.0, 1.0, 0.8])
whiteRoundedView.layer.masksToBounds = false
whiteRoundedView.layer.cornerRadius = 10
cell.contentView.addSubview(whiteRoundedView)
cell.contentView.sendSubview(toBack: whiteRoundedView)

I think that it's better assign this 10px from storyboard (or xib).
You can insert a leading space constraint in your UIView (designed in your tableViewCell).
So automatically you no longer work with frames that which often gives problem...

You should bring your whiteRoundedView to the front of the contentView. Right now the whiteRoundedView is behind the cell's contentView.
cell.contentView.bringSubview(toFront: whiteRoundedView)

Related

How can I add the safe area to the view height?

I am creating a top "banner" and I want it to cover the safe area and some more.
I can't seem to find how to cover the Safe area.
The first picture is the desired effect, the second is the effect on notched iPhones.
Desired Effect
What's Happening
How can I add the safe area to the desired value of height?
Code:
let shadowView = UIView( frame: CGRect( x: -10, y: -20, width: (view.frame.width+20), height: 90 ) )
view.addSubview( shadowView )
shadowView.backgroundColor = .clear
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowOpacity = 0.3
shadowView.layer.shadowOffset = CGSize(width: 5, height: 3)
shadowView.layer.shadowRadius = 4.0
let titleView = UIView( frame: CGRect( x: 0, y: 0, width: ( shadowView.frame.width ), height: 90 ) )
shadowView.addSubview( titleView )
titleView.backgroundColor = .systemGreen
titleView.layer.cornerRadius = 45
titleView.layer.masksToBounds = true
The problem is here:
let shadowView = UIView( frame: CGRect( x: -10, y: -20, width: (view.frame.width+20), height: 90 ) )
You are hardcoding the frame - don't do this! Well, a height of 90 is fine. But the x: -10, y: -20, width: (view.frame.width+20) is terrible. Not all phones are the same size.
Technically, you could calculate the safe area inset height as NoeOnJupiter commented, but this is still pretty bad. What happens when the user rotates their device, and the notch moves? It sounds like a lot of work.
What you want is Auto Layout and the Safe Area. With Auto Layout, simply define some constraints, then watch your UIViews look great on all screen sizes. Then, the Safe Area defines what parts of the screen are "safe," meaning "not covered by notches or rounded screen corners."
So, you can pin shadowView to the edges of the screen (beyond the notch/safe area), and add the .systemGreen background color. Then, make titleView 90 points high, pinning it vertically to shadowView. Just note how titleView.topAnchor is pinned to shadowView.safeAreaLayoutGuide.topAnchor — this makes it stay clear of the notch.
let shadowView = UIView() /// green background with shadow and corner radius
shadowView.translatesAutoresizingMaskIntoConstraints = false
shadowView.backgroundColor = .systemGreen /// put the background color here instead of on `titleView`, because this view stretches beyond the notch
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowOpacity = 0.3
shadowView.layer.shadowOffset = CGSize(width: 5, height: 3)
shadowView.layer.shadowRadius = 4.0
shadowView.layer.cornerRadius = 45
shadowView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner] /// only round the bottom corners
view.addSubview(shadowView)
let titleView = UIView() /// container for title label.
titleView.translatesAutoresizingMaskIntoConstraints = false
shadowView.addSubview(titleView)
let titleLabel = UILabel() /// the title label itself
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleView.addSubview(titleLabel)
titleLabel.text = "Catalogues"
titleLabel.font = UIFont.systemFont(ofSize: 36, weight: .medium)
NSLayoutConstraint.activate([
/// constrain `shadowView`
shadowView.topAnchor.constraint(equalTo: view.topAnchor),
shadowView.rightAnchor.constraint(equalTo: view.rightAnchor),
shadowView.leftAnchor.constraint(equalTo: view.leftAnchor),
/// constrain `titleView`
titleView.topAnchor.constraint(equalTo: shadowView.safeAreaLayoutGuide.topAnchor), /// most important part!
titleView.heightAnchor.constraint(equalToConstant: 90), /// will also stretch `shadowView` vertically
titleView.rightAnchor.constraint(equalTo: shadowView.rightAnchor),
titleView.leftAnchor.constraint(equalTo: shadowView.leftAnchor),
titleView.bottomAnchor.constraint(equalTo: shadowView.bottomAnchor),
/// constrain `titleLabel`
titleLabel.centerXAnchor.constraint(equalTo: titleView.centerXAnchor),
titleLabel.centerYAnchor.constraint(equalTo: titleView.centerYAnchor)
])
Result:
iPhone 8
iPhone 12
For further reading, I have a blog post on this topic.

Swift - Adjust size on separator of UITableViewCell

I have at problem with my cells in a UITableView. I have used the Attribute Inspector to adjust the size. Like this:
But the adjustment only applied on the cells with content. How do I make the separator to be the same size for the whole tableview using Swift or the Attribute Inspector?
For your question, you can try this
tableView.tableFooterView = UIView()
Another way you can do like this.
Then,
In cellForRowAtIndexPath
tableView.separatorStyle = .none
let horizontalGap = 15.0 as CGFloat
// As you want to have equal gaping in left & right side, you have to position the view's origin.x to the constant and have to have the width minus the double of that constant.
let seperatorView = UIView(frame: CGRect(x: horizontalGap, y: cell.frame.size.height - 1, width: cell.frame.size.width - horizontalGap * 2.0, height: 1))
seperatorView.backgroundColor = UIColor.red
cell.addSubview(seperatorView)
In Storyboard
Change Separator as None in Attributes Inspector. Drag UIView and place it inside your cell . Give constraints like, Leading 15, Trailing 15, Bottom 0 and height 1. Change background color to red

Reproducing Music App's NavigationBar Animation

In my project I want to achieve a very similar animation like in the Artist-ViewController of the stock Music App.
When the UITableView scrolls to a specific offset the navigationBar's tintColor, the color of the title and the color of the statusbar changes.
To achieve that I added an UIView (I named it containerView) as a subView of the UINavigationBar and inside that containerView I added a UIBlurEffect. Now when the tableView scrolls I am listening to scrollViewDidScroll to change the earlier named attributes which works really good.
containerView.frame = CGRect(x: 0, y: -(statusBarHeight), width: UIScreen.main.bounds.width, height: frame.height + statusBarHeight)
containerView.clipsToBounds = true
insertSubview(containerView, at: 0)
let blurEffect = UIBlurEffect(style: .extraLight)
overlayView.effect = blurEffect
overlayView.backgroundColor = unOverlayColor
let height = frame.height + statusBarHeight
overlayView.frame = CGRect(x: 0, y: containerView.frame.height, width: containerView.frame.width, height: height)
containerView.addSubview(overlayView)
My only problem is that the containerView is placed above the UINavigationBar's navigationItems and therefore hides them.
So my question is how can I add the containerView behind the navigationItems to the UINavigationBar?
I figured out that it has to be something with the way how navigationBars are handled in iOS 11 because on iOS 10 everything works fine.

Add Corner Radius and drop shadow to UICollectionViewCell Swift 3

I'm trying to add corner radius + dropdown shadow to my UICollectionView Cell,
my Cell sturcuture is like this:
I added view to add shadow on it, and try to add corner radius to the to subviews: the white one and the imageview, I used the following code:
let frame = CGRect(x:0, y: 0, width: UIScreen.main.bounds.width, height: 80)
shadowingViewOutlet.layer.masksToBounds = false
shadowingViewOutlet.layer.shadowColor = UIColor.black.cgColor
shadowingViewOutlet.layer.shadowOffset = CGSize(width: CGFloat(0.0), height: CGFloat(3.0))
shadowingViewOutlet.layer.shadowOpacity = 0.5
if shadowingViewOutlet.layer.shadowPath != nil {
shadowingViewOutlet.layer.shadowPath = UIBezierPath(roundedRect:frame, cornerRadius:3).cgPath
}
but that dosen't work fine!
Anyone try to apply the same functionlaity to UICollectionViewCell and have a result in it?
please help.
Thanks.

ios - Left Align Image and Place Text in Center of UIButton

I have been trying to align an image on the left of a button while also placing some text in the center of a button. I have been following this stack overflow post: Left-align image and center text on UIButton.
I followed one of the answers that worked the best for me. Here is the code for that answer:
#IBDesignable class LeftAlignedButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
if let image = imageView?.image {
let margin = 30 - image.size.width / 2
let titleRec = titleRect(forContentRect: bounds)
let titleOffset = (bounds.width - titleRec.width - image.size.width - margin) / 2
contentHorizontalAlignment = UIControlContentHorizontalAlignment.left
imageEdgeInsets = UIEdgeInsetsMake(0, margin, 0, 0)
titleEdgeInsets = UIEdgeInsetsMake(0, titleOffset, 0, 0)
}
}
}
Even though this gets me really close to my desired result it does not fully accomplish what I am looking for.
Here is what my current buttons look like:
As you can probably see the text in the google button, even though centered for that particular button does not correspond with how the facebook button's text is centered. Also, the images are a bit too big, but I don't know how to make them smaller.
Here is the result I am looking for:
To conclude, the questions I have are how do I properly center the google button's text so it corresponds with the design of the facebook button and how do I make the images smaller.
You can also try this one. Works well with different image widths and with different titles.
extension UIButton {
func moveImageLeftTextCenter(imagePadding: CGFloat = 30.0){
guard let imageViewWidth = self.imageView?.frame.width else{return}
guard let titleLabelWidth = self.titleLabel?.intrinsicContentSize.width else{return}
self.contentHorizontalAlignment = .left
imageEdgeInsets = UIEdgeInsets(top: 0.0, left: imagePadding - imageViewWidth / 2, bottom: 0.0, right: 0.0)
titleEdgeInsets = UIEdgeInsets(top: 0.0, left: (bounds.width - titleLabelWidth) / 2 - imageViewWidth, bottom: 0.0, right: 0.0)
}
}
Usage: myButton.moveImageLeftTextCenter()
#Rohan The issue is let margin = 30 - image.size.width / 2. You are using image width to find out the margin.The Images (facebook and google) size are different(I am assuming). So according to your code, label left margin must change with image width. So if you want to achieve You have to keep both image size similar according to your code.

Resources