round bottomRight with byRoundingCorners not work - ios

I'm trying to make round corner for topLeft and rightBottom, the top round work well but leftBottom still rectangle,
I searched a lot I think it's overlap issue but don't know how to fix it, please any help?
P.S. it's work well just in IPhone Xs Max
import UIKit
#IBDesignable
class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setRadius()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setRadius()
}
override func prepareForInterfaceBuilder() {
setRadius()
}
func setRadius()
{
let cornerRadius = 18.0
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .bottomRight], cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
let maskLayer = CAShapeLayer()
self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
maskLayer.frame = self.bounds
maskLayer.path = path.cgPath
self.layer.mask = maskLayer
}
}

Try this
let your_Frame = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))//define your frame size you want
your_Frame.layer.cornerRadius = 25//deine the radius you want
your_Frame.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner]
view.addSubview(your_Frame)

Related

Custom #IBDesignable UIButton crashes Xcode

I wanted to design a rounded button with a shadow for my iOS project in Swift. So I came up with the following custom button class:
import UIKit
#IBDesignable class MainButton: UIButton {
private var shadowLayer: CAShapeLayer!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
let image = createBackgroundImage()
setBackgroundImage(image, for: UIControl.State.normal)
clipsToBounds = true
contentEdgeInsets = UIEdgeInsets(top: 5, left: 20, bottom: 5, right: 20)
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 3)
layer.shadowOpacity = 0.2
layer.shadowRadius = 6
}
func createBackgroundImage() -> UIImage {
let rect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
let color = UIColor.white
color.setFill()
UIBezierPath(roundedRect: rect, cornerRadius: frame.height * 0.5).addClip()
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
As soon as I set this class for a button in my Storyboard the "IBDEsignablesAgent-iOS" process takes nearly 100% of my CPU and Xcode hangs it self. This behavior makes it near impossible to debug the problem correctly.
I'm quite certain I do something in the wrong order or wrong method. But I have no clue how to solve it. Hopefully someone here can point me the right direction.
Thanks,
Jens
Simply check that the size of the view actually changed:
private var lastSize: CGSize = .zero
override func layoutSubviews() {
super.layoutSubviews()
guard frame.size != lastSize else { return }
lastSize = frame.size
...
}
Creating shadows is slow and layoutSubviews is called tens of times every second (basically, once every frame).
My custom button with some shadow and rounded corners, I use it directly within the Storyboard, no need to touch it programmatically.
class RoundedCornerButtonWithShadow: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.layer.masksToBounds = false
self.layer.cornerRadius = self.frame.height/2
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath
self.layer.shadowOffset = CGSize(width: 0.0, height: 3.0)
self.layer.shadowOpacity = 0.5
self.layer.shadowRadius = 1.0
}
}

Rounded UITableViewCell only bottom or top corners but it doesn't work Swift iOS 10

I want to round top and bottom corners of 2 UITableViewCell like this : It's what I get on iOS 11
What I want
But I got this on iOS 10:
Result rectShape.bounds = self.bounds
With that code :
UITableViewCell of blue view
import UIKit
class ProductDescriptionTableViewCell: UITableViewCell {
var ProductDescription: UITextView!
public var container: UIView!
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
// Set the width of the cell
self.bounds = CGRect(x: self.bounds.origin.y + 16, y: self.bounds.origin.y, width: self.bounds.size.width - 16, height: self.bounds.size.height)
super.layoutSubviews()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.backgroundColor = UIColor.blue
if #available(iOS 11.0, *) {
self.layer.masksToBounds = true
self.layer.cornerRadius = 10
self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
} else {
let rectShape = CAShapeLayer()
rectShape.bounds = self.bounds// CGRect(x: self.bounds.origin.x + 16, y: self.bounds.origin.y, width: self.bounds.size.width - 16, height: self.bounds.size.height)
rectShape.position = self.center
rectShape.path = UIBezierPath(roundedRect: rectShape.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10)).cgPath
self.layer.backgroundColor = UIColor.red.cgColor
//Here I'm masking the textView's layer with rectShape layer
self.layer.mask = rectShape
}
}
}
UITableViewCell of purple view
import UIKit
class ProductTitleTableViewCell: UITableViewCell {
var ProductTitle: UILabel!
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
// Set the width of the cell
self.bounds = CGRect(x: self.bounds.origin.y + 16, y: self.bounds.origin.y, width: self.bounds.size.width - 16, height: self.bounds.size.height)
super.layoutSubviews()
}
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.backgroundColor = UIColor.purple
if #available(iOS 11.0, *) {
self.layer.masksToBounds = true
self.layer.cornerRadius = 10
self.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
} else {
let rectShape = CAShapeLayer()
rectShape.bounds = self.bounds//CGRect(x: self.bounds.origin.x + 16, y: self.bounds.origin.y, width: self.bounds.size.width - 16, height: self.bounds.size.height)
rectShape.position = self.center
rectShape.path = UIBezierPath(roundedRect: rectShape.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 10, height: 10)).cgPath
self.layer.backgroundColor = UIColor.green.cgColor
//Here I'm masking the textView's layer with rectShape layer
self.layer.mask = rectShape
}
}
}
if I replace self.bounds by the CGRect in comment I got that :
With rectShape.bounds = CGRect(x: self.bounds.origin.x + 16, y: self.bounds.origin.y, width: self.bounds.size.width - 16, height: self.bounds.size.height)
I try to change the self.bounds at the beginning of init() but it's doesn't work too
And I also try to put the code which change corners in layoutSubviews() but in that case the UITableViewCell disappear
I don't one to use only one UITableViewCell and round his corners I really need to round bottom and top corners on to separate UITableViewCell
If you know how I can fix that I will be very grateful
Thank you for your time
Add the following extension:
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
}
Then call it from layout subviews like below:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
headerView.roundCorners([UIRectCorner.topLeft, UIRectCorner.topRight], radius: kTableViewCornerRadius)
}
Well, i am using this very simple extension of UIView to make corners round. In cellForRowAt delegate method, after dequeing the cell, just call
cell.makeCornersRound()
extension UIView {
public func makeCornersRound () {
self.layer.cornerRadius = 8
self.clipsToBounds = true
}
}

UITableViewCell TopLeft and BottomLeft Corners not working

I'm new to iOS development and trying to create a custom UITableViewCell that has a background which top-left and bottom-left corners I want to round, but it only works for the top-left corner.
Here is my code (Swift 3):
override func awakeFromNib() {
super.awakeFromNib()
let bgViewMask = CAShapeLayer()
let bgViewPath = UIBezierPath(
roundedRect: bgView.bounds,
byRoundingCorners: [.topLeft, .bottomLeft],
cornerRadii: CGSize(width: 8, height: 8)
)
bgViewMask.frame = bgView.bounds
bgViewMask.path = bgViewPath.cgPath
bgView.layer.mask = bgViewMask
}
I also tried this in layoutSubviews()
override func layoutSubviews() {
super.layoutSubviews()
//code here
}
but it didn't work as well.
If I use bgView.layer.cornerRadius = 8 it works for all corners.
Am I doing anything wrong?
You can try this:
import UIKit
class CustomImageView: UIImageView {
override public func layoutSubviews() {
super.layoutSubviews()
self.roundUpCorners([.topLeft, .bottomLeft], radius: 8)
}
}
extension UIView {
func roundUpCorners(_ 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
}
}

UIView rounded Corner - Swift 2.0?

Ill try to update some projects to Swift 2.0. I´ve got a View, with a rounded corner top left. Everything works fine in Swift < 1.2, but now, there is no rounded corner anymore.
No Warnings, no Errors, just no rounded corner.
This is how it works in Swift < 1.2.
let maskPath = UIBezierPath(roundedRect: contentView.bounds,byRoundingCorners: .TopLeft, cornerRadii: CGSize(width: 10.0, height: 10.0))
let maskLayer = CAShapeLayer(layer: maskPath)
maskLayer.frame = contentView.bounds
maskLayer.path = maskPath.CGPath
contentView.layer.mask = maskLayer
Anyone know whats wrong here? Ill dont find any changes in the documentation.
There's nothing wrong with this piece of code in Swift 2.0–2.1. Are you sure there isn't something else before or after this code snippet, that's affecting your view?
Here's a quick Playground with your code:
Swift 4.0 - 5.0
You can use a simple class I have created to create a UIView and add rounded corners directly from Storyboard
You can find the class here
import Foundation
import UIKit
#IBDesignable class SwiftRoundView: UIView {
#IBInspectable fileprivate var borderColor: UIColor = .white { didSet { self.layer.borderColor = self.borderColor.cgColor } }
#IBInspectable fileprivate var borderWidth: CGFloat = 0.00 { didSet { self.layer.borderWidth = self.borderWidth } }
#IBInspectable fileprivate var cornerRadius: CGFloat = 0.00 { didSet { self.layer.cornerRadius = self.cornerRadius } }
init(x: CGFloat = 0.0, y: CGFloat = 0.0, width: CGFloat, height: CGFloat, cornerRadius: CGFloat = 0.0, borderWidth: CGFloat = 0.0, borderColor: UIColor = .white) {
self.cornerRadius = cornerRadius
self.borderWidth = borderWidth
self.borderColor = borderColor
super.init(frame: CGRect(x: x, y: y, width: width, height: height))
setupView()
}
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
fileprivate func setupView() {
self.layer.cornerRadius = cornerRadius
self.layer.borderWidth = borderWidth
self.layer.borderColor = borderColor.cgColor
self.clipsToBounds = true
}
}

UIBezierPath - byRoundingCorners - Rect

I have a very easy view controller..
import UIKit
class ViewController: UIViewController {
let f = TstKocka(frame: CGRectMake(100,100, 150, 150))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(f)
}
}
And I have a UIView class:
class TstKocka: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func drawRect(rect: CGRect) {
var path = UIBezierPath(roundedRect: rect, byRoundingCorners: UIRectCorner.AllCorners, cornerRadii: CGSize(width: 2.0, height: 2.0))
path.lineWidth = 1.0
path.stroke()
}
}
And I'm trying to create a rounded rect but I don't know how to do. I've read lot of tutorials but none of them worked for me.Please help me.
since you are not providing a fill color i guess your rect shall have a clear color. to make that work change your initwithframe to the following:
override init(frame: CGRect) {
super.init(frame: frame)
opaque = false
}
then increase cornerradii value (to 20.0, 20.0 for example) to see that it works! :)
EDIT
filling is actually as simple as stroking:
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: UIRectCorner.AllCorners, cornerRadii: CGSize(width: 20.0, height: 20.0))
path.lineWidth = 1.0
UIColor.blueColor().setFill() // or whatever fill color you like
path.fill()
UIColor.redColor().setStroke()
path.stroke()
If you are trying to create a rounded rect view that clips the content, you should use layer masks or the simple -cornerRadius property on the views layer, setting also the -borderWidth.
If you just want a view background rounded rect, before stroking you should set the stroke color.
I don't know swift but in objC could be something like this
- (void) drawRect:(CGRect) rect {
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:5.0];
[[UIColor redColor] setStroke];
[bezierPath stroke];
}
In Swift probably:
override func drawRect(rect: CGRect) {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: UIRectCorner.AllCorners, cornerRadii: CGSize(width: 2.0, height: 2.0))
UIColor.redColor().setStroke()
path.lineWidth = 1.0
path.stroke()
}

Resources