Swift: Button round corner breaks contraints - ios

I have a tableview with custom cell loaded via xib and in that cell I have status button which bottom right corner should be rounded. The button has constraints Trailing/Leading/Bottom space to superview=0 and height=30.
Without rounding it is working perfectly, as soon as I round one corner for example bottom right the constraints breaks
self.btnStatus.roundCorners(corners: [.bottomRight], radius: 7.0, borderWidth: nil, borderColor: nil)
Some guys here suggesting to call layoutSubviews() but it didn't helped me.
To be more specific I've created simple project where you can have a look into whole project.
Correct Link
ButtonRoundCorner.zip

You can get more reliable results by subclassing your button and placing your "rounding" code by overriding its layoutSubviews() function.
First, if you want to add a border, you don't want to add multiple "border sublayers" ... so change your UIView extension to this:
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat, borderWidth: CGFloat?, borderColor: UIColor?) {
let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let maskLayer = CAShapeLayer()
maskLayer.frame = self.bounds
maskLayer.path = maskPath.cgPath
self.layer.mask = maskLayer
self.layer.masksToBounds = true
if (borderWidth != nil && borderColor != nil) {
// remove previously added border layer
for layer in layer.sublayers! {
if layer.name == "borderLayer" {
layer.removeFromSuperlayer()
}
}
let borderLayer = CAShapeLayer()
borderLayer.frame = self.bounds;
borderLayer.path = maskPath.cgPath;
borderLayer.lineWidth = borderWidth ?? 0;
borderLayer.strokeColor = borderColor?.cgColor;
borderLayer.fillColor = UIColor.clear.cgColor;
borderLayer.name = "borderLayer"
self.layer.addSublayer(borderLayer);
}
}
}
Next, add a UIButton subclass:
class RoundedButton: UIButton {
var corners: UIRectCorner?
var radius = CGFloat(0.0)
var borderWidth = CGFloat(0.0)
var borderColor: UIColor?
override func layoutSubviews() {
super.layoutSubviews()
// don't apply mask if corners is not set, or if radius is Zero
guard let _corners = corners, radius > 0.0 else {
return
}
roundCorners(corners: _corners, radius: radius, borderWidth: borderWidth, borderColor: borderColor)
}
}
This gives you a couple benefits: 1) It will update its mask layer frame when the button frame changes (rotating the device, for example), and 2) you could set these values either from your custom cell class or from cellForRowAt.
Either way, change your btnStatus class from UIButton to RoundedButton - both in your storyboard and the #IBOutlet connection.
Then change your CustomTableViewCell to this:
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var btnStatus: RoundedButton!
override func awakeFromNib() {
super.awakeFromNib()
// set up corner maskign
btnStatus.corners = .bottomRight
btnStatus.radius = 7.0
// set if desired
// btnStatus.borderWidth = 2.0
// btnStatus.borderColor = .blue
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
And finally, your cellForRowAt function becomes:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
return cell
}
That should do it...

I looked at your code. The problem is that your roundCorners function is depending on your view's bounds to set your layer's properties and you are calling roundCorners in awakeFromNib at which point your cell has the same bounds as in the NIB file because autolayout has not been calculated yet. You need to move your roundCorners call into layoutSubviews, so it gets called after autolayout is done computing your bounds.
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var btnStatus: UIButton!
override func layoutSubviews() {
super.layoutSubviews()
self.btnStatus.roundCorners(corners: [.bottomRight], radius: 7.0, borderWidth: nil, borderColor: nil)
}
}
EDIT also add cell.setNeedsLayout() to cellforRowAt to force layoutSubviews to be called before the cell is drawn for the first time.

Maybe your button is overlapping since it doesn't have an upper constraint? Try adding a bright border and see if you can see the top part, if not try adding a constraint to the top. Also, instead of giving it a static height, try making it a proportional height to the object above it (maybe the screen size of your device is causing it to overlap)

Related

how to set corner radius for top left and top right of a UIView on tableview Custom Cell?

ViewController.swift
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mycell") as! CustomTableViewCell
cell.backgroundColor = UIColor.clear
cell.nameLbl.text = "\(adminNmaes[indexPath.row])"
cell.aboutLbl.text = "\(aboutarray[indexPath.row])"
if indexPath.row == 0
{
cell.view1.roundCorners(corners: [.topLeft,.topRight], radius: 10)
// tableView.reloadData()
}
return cell
}
extension UIView {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
i setup custom cell class using autolayout and used an extension to apply cornerradius for only 1st cell. i aslo want to give corner radius for bottom left and bottom right for the footer and also give it a padding of 10. any help is appreciated.thanks in advance.
As of iOS11, CALayer has property maskedCorners:
var maskedCorners: CACornerMask { get set }
In your case you would use:
cell.contentView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMinYCorner]
This masks the top left and right corners to whatever cornerRadius you've set.
Also you need to make sure that the contentView is clipping its subviews so that they can conform to the shape
cell.contentView.clipsToBounds = true

UIBezierPath not cleared on redraw

I have custom UIView in which I draw a UIBezierPath. This view is used in a UITableViewCell. So when I scroll, the custom view's bezier path gets redrawn. The problem is that the new path draws over old path drawings (the context isn't cleared properly). I'm calling setNeedsDisplay() on the table cell fetch and I've also set clearsContextBeforeDrawing = true for the view. The only thing that clears up the old drawing is calling context.clear(rect) but this isn't at all ideal since I lose the background (it becomes black).
Any ideas on how to fix this?
class CustomView: UIView {
var percentage: CGFloat = 0 {
didSet {
setNeedsDisplay()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
clearsContextBeforeDrawing = true
contentMode = .redraw
clipsToBounds = false
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
super.draw(rect)
// NOTE: don't really like doing this
let context = UIGraphicsGetCurrentContext()!
context.clear(rect)
let center = CGPoint(x: self.bounds.size.width/2, y: self.bounds.size.height/2)
let path = UIBezierPath(arcCenter: center,
radius: self.bounds.size.width/2-10,
startAngle: 0.5 * .pi,
endAngle: (-2.0 * self.percentage + 0.5) * .pi,
clockwise: false)
path.lineWidth = 4
UIColor.red.setStroke()
path.stroke()
}
}
This is where my cell and custom uiview gets set.
override func tableView(_ tableView: UITableView, cellForItemAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
let num = list[indexPath.item]
let percentage = CGFloat(num) / 10
cell.customView.percentage = percentage // Custom view should get redrawn after this call
return cell
}
I think the problem is merely that your drawing is huge and strays outside the cell because your views do not clip to bounds. That's incoherent. Each cell needs to draw just its own content.
In other words, the overlapping you are seeing has nothing to do with the custom view drawing; it has to do with the cell drawing. You are infecting the neighboring cells with your drawing.
By the way, you say:
but this isn't at all ideal since I lose the background (it becomes black)."
You can fix that by saying self.backgroundColor = .clear in your init.

Issue in setting corner radius of view inside cell?

I have a custom UITableView cell.I am setting it's bottom left & bottom right corner radius.I am setting corner radius in cellForAtindexPath.Below is the code for that
if indexPath.row == 9 {
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
recipeInfoCell.layoutSubviews()
recipeInfoCell.layoutIfNeeded()
} else {
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
recipeInfoCell.layoutSubviews()
}
Now when i first launch the tableview then it does not set any corner radius. But when i scroll again then it is setting the corner radius.
I have created an extension of UIView in which there is one function which is setting the corner radius
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
Please tell how do i resolve this ?
I do not think it is a good idea to set corner radius in cellForRow atIndexPath. The reason being, this function is called many times during the lifetime of UITableView and you only need to set the corner radius only once and that too when the cell is initialised. Changing the corner radius based on indexPath will also affect the UITableView's performance.
A better way to this would be to create two cells, one with corner radius as 0 and another with 10 and the use those cells based on indexPath.
Then you can put your cornerRadius set logic in layoutSubview function in your custom cell.
If you want to do it in your tableView methods only, the correct way is to do it in willDisplayCell because after that call, cell's layoutSubviews function in called.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row % 2 == 0 {
let path = UIBezierPath(roundedRect: cell.contentView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
let mask = CAShapeLayer()
mask.path = path.cgPath
cell.contentView.layer.mask = mask
} else {
let path = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 0, height: 0))
let mask = CAShapeLayer()
mask.path = path.cgPath
cell.contentView.layer.mask = mask
}
}
UPDATE: May 19, 2017
The above concept will work fine when the view that you want to round and put shadow on is the same size as the cell's content view. But if it is anything different than that, it won't work.
The reason for the above statement is that at the time when willDisplayCell is called, where the above code is using cell.contentView.bounds, the other views are not calculated yet. So when we will be using another view, we will have to use that view's bounds to calculate the mask's frame which we will be different from the actual one.
After reading up on this a bit, I found out that, to do this kind of a thing is by overriding draw(_ rect: CGRect) function of UITableViewCell. Because at this point, the view's size has been properly calculated and we can create a correct frame.
Below is the code from custom UITableViewCell class:
var shadowLayer = CAShapeLayer()
override func draw(_ rect: CGRect) {
let path = UIBezierPath(roundedRect: self.outerView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.outerView.layer.mask = mask
// Handle Cell reuse case
shadowLayer.removeFromSuperlayer()
shadowLayer.shadowPath = path.cgPath
shadowLayer.frame = self.outerView.layer.frame
print(shadowLayer.frame)
shadowLayer.shadowOffset = CGSize(width: 0, height: 0)
shadowLayer.shadowColor = UIColor.black.cgColor
shadowLayer.shadowOpacity = 0.9
self.contentView.layer.insertSublayer(shadowLayer, below: self.outerView.layer)
super.draw(rect)
}
put round corner code in main queue like this :
if indexPath.row == 9 { dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
})} else{
dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
}) }
Try writing these lines of code in layoutSubviews() of your custom UITableViewCell
override func layoutSubviews() {
super.layoutSubviews()
self.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
}
For acquiring that in swift only I use to create one subclass of the UIButton like below
(in any .swift file of project)
//MARK: Custom Class for UIView
open class CustomView: UIView {
open func drawViewsForRect(_ rect: CGRect) {
fatalError("\(#function) must be overridden")
}
open func updateViewsForBoundsChange(_ bounds: CGRect) {
fatalError("\(#function) must be overridden")
}
}
Then define the below methods in same or deferent .swift file like this
//MARK: - UIView Property Class
#IBDesignable open class CView : CustomView{
#IBInspectable dynamic open var borderColor: UIColor = UIColor.clear{
didSet{
updateBorderColor()
}
}
#IBInspectable dynamic open var borderWidth: CGFloat = 1.0{
didSet{
updateBorderWidth()
}
}
#IBInspectable dynamic open var cornerRadius: CGFloat = 0.0{
didSet{
updateBorderRadius()
}
}
#IBInspectable dynamic open var shadowColor: UIColor?{
didSet{
updateShadowColor()
}
}
#IBInspectable dynamic open var shadowRadius: CGFloat = 0.0{
didSet{
updateShadowRadius()
}
}
#IBInspectable dynamic open var shadowOpacity: Float = 0.0{
didSet{
updateShadowOpacity()
}
}
#IBInspectable dynamic open var shadowOffSet: CGSize = CGSize(width: 0.0, height: 0.0){
didSet{
updateShadowOffset()
}
}
//Update Borders Properties
open func updateBorderColor(){
self.layer.borderColor = borderColor.cgColor
}
open func updateBorderRadius(){
self.layer.cornerRadius = cornerRadius
}
open func updateBorderWidth(){
self.layer.borderWidth = borderWidth
}
//Update Shadow Properties
open func updateShadowColor(){
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOpacity(){
self.layer.shadowOpacity = shadowOpacity
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowRadius(){
self.layer.shadowRadius = shadowRadius
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOffset(){
self.layer.shadowOffset = CGSize(width: shadowOffSet.width, height: shadowOffSet.height)
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
}
Then just assign the CView class in storyboard at design time for any view controller and just provide the required values for the properties for that in side the attribute inspector for that view
In Storyboard
1) Class of the View Like this
2) Set property like this
3) This will show view in side the design like this
With this you even been able to see the shadow or corner radius directly in your design builder i.e. in side the storyboard view like the third image.
You want a specific cell to round corner if i understand correctly. here is my solution.Though i am bit late but i try to help others. :) I just added my solution as a picture.
Step 1:
Created a custom Cell and did some necessary steps.
Below is the code for Rounded bottom left and bottom right.Sorry for poor coding style:
Below is My view controller's configuration for showing tableView with rounded cells.
And Below is the moment of truth:
I took reference from (https://stackoverflow.com/a/44067058/2781088) and modified the code and now it's working for me:
Add below code to your custom cell class:
enum cellStyle: Int {
case Normal = 0, Rounded
}
class CustomTableCell:UITableViewCell {
var cellType: Int = 0 {
didSet {
let maskLayer = CAShapeLayer()
let cell: cellStyle = cellStyle(rawValue: cellType)!
switch cell {
case .Normal:
let normal = UIBezierPath(roundedRect: self.viewMain.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 0, height: 0))
maskLayer.path = normal.cgPath
self.viewMain.layer.mask = maskLayer
case .Rounded:
let rounded = UIBezierPath(roundedRect: self.viewMain.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 10, height: 10))
maskLayer.path = rounded.cgPath
self.viewMain.layer.mask = maskLayer
}
}
}
}
In your ViewController->cellForRowAt --- Call below code on Main Queue
DispatchQueue.main.async {
if totalRows == index + 1 { //write your condition
cell.cellType = cellStyle.Rounded.rawValue
} else {
cell.cellType = cellStyle.Normal.rawValue
}
cell.layoutSubviews()
cell.layoutIfNeeded()
}
This worked for me:
view.clipsToBounds = true
view.layer.cornerRadius = value
view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
Based on my experience, this is what works for me to get the dynamic-sized layers work properly.
//Inside the cell or the view class
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
if layer === self.layer {
//Do any dynamic-layer update here
myViewToRound.layer.cornerRadius = myViewToRound.bounds.width/2
}
}
here, replace myViewToRound with the UIView subclass that you want to be rounded inside your cell/view

Delete border of UIView when app changes size class

I have a blue view with a white dashed border. As you can see from the image below, once the app is rotated the view changes its dimensions and the border doesn't adjust to the view's new width and height.
I need to find a way to
Know when the view controller changes its size - perhaps using viewWillTransitionToSize.
Delete the previously drawn border, if any.
Add a new border to the view - in the view's drawRect method.
How can I delete the border previously drawn on the view?
#IBOutlet weak var myView: UIView!
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition(nil, completion: {
_ in
self.myView.setNeedsDisplay()
})
}
class RenderView: UIView {
override func drawRect(rect: CGRect) {
self.addDashedBorder()
}
}
extension UIView {
func addDashedBorder() {
let color = UIColor.whiteColor().CGColor
let shapeLayer:CAShapeLayer = CAShapeLayer()
let frameSize = self.frame.size
let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height)
shapeLayer.bounds = shapeRect
shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height/2)
shapeLayer.fillColor = UIColor.clearColor().CGColor
shapeLayer.strokeColor = color
shapeLayer.lineWidth = 6
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.lineDashPattern = [6,3]
shapeLayer.path = UIBezierPath(roundedRect: shapeRect, cornerRadius: 5).CGPath
self.layer.addSublayer(shapeLayer)
}
}
Download sample project here.
This is not the right way to do things. Each time your RenderView is redrawn, its drawRect method will be called, and addDashedBorder will add a new layer to your view.
drawRect is for drawing inside of your view using CoreGraphics or UIKit, not CoreAnimation. Inside that method, you should just draw, nothing else. If you want to use it a layer, layoutSubviews is a better place to add it, and to update it to match the view.
Here are two ways to solve your problem. Both update the border correctly, and animate the border smoothly when the device is rotated.
Alternative 1: Just draw the border in drawRect, rather than using a separate shape layer. Also, set your view's contentMode so it automatically redraws when its size changes.
class ViewController: UIViewController {
#IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.myView.contentMode = .Redraw
}
}
class RenderView: UIView {
override func drawRect(rect: CGRect) {
let path = UIBezierPath(roundedRect: self.bounds, cornerRadius: 5)
path.lineWidth = 6
let pattern: [CGFloat] = [6.0, 3.0]
path.setLineDash(pattern, count: 2, phase: 0)
UIColor.whiteColor().setStroke()
path.stroke()
}
}
Alternative 2: Continue to use CAShapeLayer, but only create a single one, by using a lazy stored property. Update the layer in an override of layoutSubviews, and if necessary, animate it alongside any changes in the view's bounds.
class ViewController: UIViewController {
#IBOutlet weak var myView: UIView!
}
class RenderView: UIView {
// Create the borderLayer, and add it to our view's layer, on demand, only once.
lazy var borderLayer: CAShapeLayer = {
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = nil
shapeLayer.strokeColor = UIColor.whiteColor().CGColor
shapeLayer.lineWidth = 6
shapeLayer.lineDashPattern = [6,3]
self.layer.addSublayer(shapeLayer)
return shapeLayer
}()
override func layoutSubviews() {
super.layoutSubviews()
// We will update the borderLayer's path to match the view's current bounds.
let newPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 5).CGPath
// We may be animating from the old bounds to the new bounds.
// If so, we want the borderLayer to animate alongside that.
// (UIView does not do this automatically, since it does not know
// anything about our borderLayer; it's at the the CoreAnimation level,
// below UIKit.)
//
// We want an animation that uses the same properties as the existing
// animation, but applies to a different value: the borderLayer's path.
// We'll find the existing animation on the view's bounds.size,
// and if it exists, add our own animation based on it that will
// apply the path change.
if let viewBoundsAnimation = self.layer.animationForKey("bounds.size") {
let pathAnimation = CABasicAnimation()
pathAnimation.beginTime = viewBoundsAnimation.beginTime
pathAnimation.duration = viewBoundsAnimation.duration
pathAnimation.speed = viewBoundsAnimation.speed
pathAnimation.timeOffset = viewBoundsAnimation.timeOffset
pathAnimation.timingFunction = viewBoundsAnimation.timingFunction
pathAnimation.keyPath = "path"
pathAnimation.fromValue = borderLayer.path
pathAnimation.toValue = newPath
borderLayer.addAnimation(pathAnimation, forKey: "path")
}
// Finally, whether we are animating or not, make the border layer show the new path.
// If we are animating, this will appear when the animation is finished.
// If we are not animating, this will appear immediately.
self.borderLayer.path = newPath
}
}
Note that neither of these alternatives require overriding viewWillTransitionToSize or traitCollectionDidChange. Those are higher-level UIViewController concepts, that may get called during device rotation, but won't happen if some other code changes your view's size. It's better to use the simple UIView-level drawRect or layoutSubviews methods, because they will always work.
Call set needs display when the view transitions.You can detect it by using this function.It works perfectly to detect orientation change
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
self.myView.setNeedsDisplay()
}

How to add mask on UIImageView in Cell - Swift

I've a tableView and I'm trying to add black mask on each image in the cell not on the whole cell just on the image. But I have two issues;
-It is masking the half cell from the left to the middle and each I scroll it is becoming darker. So please where would be my issue?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! PlacesTableViewCell
cell.backgroundImage.sd_setImageWithURL(NSURL(string: place.Image), placeholderImage: nil, options: .HighPriority)
}
class PlacesTableViewCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
maskArrangement()
}
func maskArrangement(){
var maskLayer = CALayer()
maskLayer.frame = CGRectMake(0, 0, backgroundImage.frame.size.width, backgroundImage.frame.size.height)
maskLayer.backgroundColor = UIColor(white: 0.0, alpha: 0.5).CGColor
//backgroundImage.layer.mask = maskLayer
backgroundImage.layer.addSublayer(maskLayer)
}
}
Every time cell is dequeued you are adding new sublayer to your backgroundImage. In this way it is getting darker when you scroll (when you dequeued your cells). I think you can add to your PlacesTableViewCell class at awakeFromNib method if it has a .xib file.
Meanwhile your image's frame should be half of the cell. Use autolayout to fix it's frame (for instance, set width and height constraints) in your PLacesTableViewCell class.
In #Shripada 's way:
class PlacesTableViewCell: UITableViewCell {
var maskLayer : CALayer
override func layoutSubviews() {
super.layoutSubviews()
maskArrangement()
}
func maskArrangement(){
if maskLayer == nil {
maskLayer.frame = CGRectMake(0, 0, backgroundImage.frame.size.width, backgroundImage.frame.size.height)
maskLayer.backgroundColor = UIColor(white: 0.0, alpha: 0.5).CGColor
//backgroundImage.layer.mask = maskLayer
backgroundImage.layer.addSublayer(maskLayer)
}
}
}
I haven't tried this code. But your solution can be like that.

Resources