ImageView doesn't change to rounded shape - ios

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
}
}

Related

how to set gradient layer width to be the same as button width?

I am new in iOS Development, I want to make gradient rounded button by using this designable class
#IBDesignable
class GradientButton: UIButton {
let gradientLayer = CAGradientLayer()
#IBInspectable
var topGradientColor: UIColor? {
didSet {
setGradient(topGradientColor: topGradientColor, bottomGradientColor: bottomGradientColor)
}
}
#IBInspectable
var bottomGradientColor: UIColor? {
didSet {
setGradient(topGradientColor: topGradientColor, bottomGradientColor: bottomGradientColor)
}
}
override func layoutSubviews() {
super.layoutSubviews()
updateCornerRadius()
}
#IBInspectable var fullRounded: Bool = false {
didSet {
updateCornerRadius()
}
}
#IBInspectable var cornerRadiusOfButton : CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadiusOfButton
}
}
func updateCornerRadius() {
layer.cornerRadius = fullRounded ? (frame.size.height / 2) : cornerRadiusOfButton
}
#IBInspectable var borderWidth: CGFloat {
set {
layer.borderWidth = newValue
}
get {
return layer.borderWidth
}
}
#IBInspectable var borderColor: UIColor? {
set {
guard let uiColor = newValue else { return }
layer.borderColor = uiColor.cgColor
}
get {
guard let color = layer.borderColor else { return nil }
return UIColor(cgColor: color)
}
}
private func setGradient(topGradientColor: UIColor?, bottomGradientColor: UIColor?) {
if let topGradientColor = topGradientColor, let bottomGradientColor = bottomGradientColor {
gradientLayer.frame = bounds
gradientLayer.colors = [topGradientColor.cgColor, bottomGradientColor.cgColor]
gradientLayer.borderColor = layer.borderColor
gradientLayer.borderWidth = layer.borderWidth
gradientLayer.cornerRadius = layer.cornerRadius
layer.insertSublayer(gradientLayer, at: 0)
} else {
gradientLayer.removeFromSuperlayer()
}
}
}
but here is the result:
as you can see the width of the gradient layer button is incorret.
here is the constraint layout I use:
I want that gradient layer to have the same width as the original button, I suspect that the problem is in this line
gradientLayer.frame = bounds
but unfortunately I don't know how to set the gradient layer width to be the same size as the original button programmatically in #IBDesignable class
could you please help me to solve this issue ? thanks in advance
Override layoutSubviews inside GradientButton and update the gradientLayer frame as,
override func layoutSubviews() {
super.layoutSubviews()
self.gradientLayer.frame = bounds
}

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
}
}

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