Round Corners UIView in Swift 4 - ios

In swift 3 I could do something like this to make my UIView corners round:
import UIKit
#IBDesignable
class DesignableView: UIView {
}
extension UIView {
#IBInspectable
var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
}
}
}
And at the storyboard I could simply change this:
Currently I'm getting a "Build failed" at the designable, but Idk why. I'm working on swift 4 and Xcode 9.
Why it's not working in swift 4?

I've tried your code and it's working fine with iOS 11.1 & Swift 4.0. (As you have mentioned it shows you an error, but it's not showing me any error)
#IBDesignable
class RoundUIView: UIView {
#IBInspectable var borderColor: UIColor = UIColor.white {
didSet {
self.layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var borderWidth: CGFloat = 2.0 {
didSet {
self.layer.borderWidth = borderWidth
}
}
#IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
self.layer.cornerRadius = cornerRadius
}
}
}
Here is result
Update:
Even your updated code is working fine, also.
#IBDesignable
class DesignableView: UIView {
}
extension UIView {
#IBInspectable
var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
}
}
}
Here is result for it:

This solution is working for me to get rounded UIView in Swift 5
view.layer.cornerRadius = 10;
view.clipsToBounds = true

swift
public func RoundFrameBackground(_ aView: UIView!, borderWidth: CGFloat!, cornerRadius: CGFloat!, borderColor: UIColor, backgroundColor: UIColor) {
aView.layer.borderWidth = borderWidth ; aView.layer.borderColor = borderColor.cgColor
aView.backgroundColor = backgroundColor ; aView.clipsToBounds = true
aView.layer.cornerRadius = cornerRadius
}
public func RoundFrameOnly(_ aView: UIView!, cornerRadius: CGFloat!) {
aView.clipsToBounds = true
aView.layer.cornerRadius = cornerRadius
}
use:
RoundFrameBackground(*a view*, borderWidth: 1, cornerRadius: 10, borderColor: UIColor.red, backgroundColor: UIColor.blue)
RoundFrameOnly(*a view*, cornerRadius: 10)

Your code seems to work fine in Swift 4.0 with a new project. However, if you are using a Storyboard and its set as LaunchScreen too, you won't be able to use custom classes directly there.
In that case just uncheck Use as Launch Screen and you should be able to build again.

Related

How can we create IBInspectable like checkmark?

I created lots of IBInspectable. But today, I observed that Xcode having some properties like this:
In the link, I marked rectangle box. I want to create custom IBInspectable like that. I don't know that is possible or not.
Any help would be appreciated.
Follow below steps to create Custom IBDesignable
Step 1:
Step 2:
step 3: add this code in created customTextView file
import UIKit
#IBDesignable
class customTextView: UITextView {
#IBInspectable var cornerRadius: CGFloat = 4.0 {
didSet{
layer.cornerRadius = cornerRadius
}
}
#IBInspectable var borderWidth: CGFloat = 0.0 {
didSet{
layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor: UIColor = UIColor.clear {
didSet{
layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var shadowOpacity: Float = 0 {
didSet{
layer.shadowOpacity = shadowOpacity
}
}
#IBInspectable var shadowColor: UIColor = UIColor.clear {
didSet{
layer.shadowColor = shadowColor.cgColor
}
}
#IBInspectable var shadowOffSet: CGSize = CGSize.zero {
didSet{
layer.shadowOffset = shadowOffSet
}
}
}
Step 4:
Step 5: Here you get you custom fields

IBInspectable not updating in storyboard but works on simulator

I can view the changes made using IBInspectable on my simulator but not in my storyboard
I tried reinstalling my Xcode but it didn't fix this issue. Here are some screenshots :
So i know my code works fine because it runs in the simulator and this is a new project altogether so I do not have any of the "Storyboard might still be loading the changes" problems.
import UIKit
extension UIView {
#IBInspectable
var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
#IBInspectable
var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layer.borderWidth = newValue
}
}
#IBInspectable
var borderColor: UIColor? {
get {
let color = UIColor(cgColor: layer.borderColor!)
return color
}
set {
layer.borderColor = newValue?.cgColor
}
}
#IBInspectable
var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.shadowOpacity = 0.4
layer.shadowRadius = shadowRadius
}
}
}
Firstly, you need #IBDesignable directive to render the updates in Storyboard whereas #IBInspectable is only to access the property directly in the Storyboard.
Secondly, you have extended the UIView class to show the inspectable properties in the Storyboard but without #IBDesignable.
Now you would think adding #IBDesignable would solve your problem but sadly you can't apply #IBDesignable on an extension like so:
#IBDesignable //won't work on an extension
extension UIView {
//...
}
You can only apply the #IBDesignable directive on a class you have access to, like so:
#IBDesignable
class MyPrettyDesignableView: UIView {
//...
}
Solution:
Bottomline is that you should subclass UIView and apply the #IBDesignable directive on this class.
Basically, your only option is:
#IBDesignable
class MyPrettyDesignableView: UIView {
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
self.layer.cornerRadius = cornerRadius
self.layer.masksToBounds = true
}
}
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
self.layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1) {
didSet {
self.layer.borderColor = borderColor.cgColor
}
}
}
Then in the storyboard, go to the view that you want designable in storyboard and change it's custom class to MyPrettyDesignableView.
Change it's custom class to your IBDesignable subclass:
Set the IBInspectable properties:
Have you checked that in Interface Builder (Editor Menu) that you have set Automatically Refresh Views and Refresh All Views?
Update: Try this:
#IBDesignable public class CustomView: UIView {
#IBInspectable var borderColor: UIColor = .white{
didSet {
layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var borderWidth: CGFloat = 2.0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var cornerRadius: CGFloat = 10.0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
#IBInspectable var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.shadowOpacity = 0.4
layer.shadowRadius = shadowRadius
}
}
override public func layoutSubviews() {
super.layoutSubviews()
clipsToBounds = true
}
}
Please update your code as below. You must have to set layer.maskToBound = false and view.clipToBounds = false
import UIKit
extension UIView {
#IBInspectable
var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
set {
layer.cornerRadius = newValue
layer.masksToBounds = newValue > 0
}
}
#IBInspectable
var borderWidth: CGFloat {
get {
return layer.borderWidth
}
set {
layer.borderWidth = newValue
}
}
#IBInspectable
var borderColor: UIColor? {
get {
let color = UIColor(cgColor: layer.borderColor!)
return color
}
set {
layer.borderColor = newValue?.cgColor
}
}
#IBInspectable
var shadowRadius: CGFloat {
get {
return layer.shadowRadius
}
set {
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.shadowOpacity = 0.4
layer.shadowRadius = shadowRadius
layer.maskToBounds = false
}
}
}
Have you tried to check Automatically Refresh Views or Refresh All Views? It works in my Xcode 9.4.1.
Editor -> Automatically Refresh Views
Assuming you have already applied #IBDesignable correctly at the declaration of a class. And assuming you have already applied #IBInspectable at the properties of the classes, then here is the trick that worked for me.
I delete and retype #IBDesignable.
sometimes even after adding #IBDesignable on the class and #IBInspectable on property definition, your Xcode might not show and refresh, so first
make sure you are using them correctly. if it is not refreshing in my case i had to close all instance of Xcode and restart the Xcode, then it will load the new fresh Interface builder files.

Swift #IBDesignable/#IBInspectable UIView styling

I'm trying to style my UIView inside table cell prototype to have it shadow for it and a couple more styling customization but for some reason when I build the project the changes are not applied.
I have the next code for it in separate file CustomView.swift
import UIKit
#IBDesignable
class CustomView: UIView {
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
#IBInspectable var shadowOpacity: Float = 0 {
didSet {
layer.shadowOpacity = shadowOpacity
}
}
#IBInspectable var shadowRadius: CGFloat = 0 {
didSet {
layer.shadowRadius = shadowRadius
}
}
#IBInspectable var shadowOffset: CGSize = CGSize(width: 0.0, height: 0.0) {
didSet {
layer.shadowOffset = shadowOffset
}
}
#IBInspectable var shadowColor: UIColor? = UIColor(red: 157/255, green: 157/255, blue: 157/255, alpha: 1.0) {
didSet {
layer.shadowColor = shadowColor?.cgColor
}
}
}
I see the field inside the "Attribute inspector" of Xcode 9
but after building it the change are not applied basically I don't see the shadow for view.
The most interesting that I'm using the same approach to customize text fields as well as buttons and this code works for UIButton/UITextField but not for UIView
Does someone know why it doesn't work for UIView ?
Any help greatly appreciated.
Thank you.
check your code:
layer.masksToBounds = cornerRadius > 0
Change that to:
layer.masksToBounds = false
And also make sure that your clipsToBounds is set to false either in code like so:
clipsToBounds = false
or in your storyboard like so:
Please Update the function
#IBInspectable
var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}

ImageView doesn't change to rounded shape

My goal is to make my the ImageView rounded and I already created a custom IBDesignable class
Code
import UIKit
#IBDesignable class MyImageView: UIImageView {
#IBInspectable var borderColor: UIColor = UIColor.clear {
didSet {
layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
}
Everything works fine already, but why is the image didn't change to rounded?
Result:
Set the clipToBounds property of UIImageView to true.
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
self.clipsToBounds = true
}
}

searchcontroller, roundedcorners not working

This view's order is like this
-View Controller
-Fake shadow view
-Container view
-Search Bar
In normal state, roundedcorner works correctly, but when I click on it, there is some shadow. When I type something on it just the view becomes rectengular
try this IBDesignable class and give rounded corner from story board
import Foundation
#IBDesignable class customView: UIView {
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor: UIColor = UIColor.gray {
didSet {
layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var shadowColor: UIColor = UIColor.gray {
didSet {
layer.shadowColor = shadowColor.cgColor
}
}
#IBInspectable var shadowOpacity: Float = 1.0 {
didSet {
layer.shadowOpacity = shadowOpacity
}
}
#IBInspectable var shadowRadius: CGFloat = 1.0 {
didSet {
layer.shadowRadius = shadowRadius
}
}
#IBInspectable var masksToBounds: Bool = true {
didSet {
layer.masksToBounds = masksToBounds
}
}
#IBInspectable var shadowOffset: CGSize = CGSize(width: 12, height: 12) {
didSet {
layer.shadowOffset = shadowOffset
}
}
}

Resources