UIKit - How to prevent default blur and focus background of UITextField? - swift

As you can see in the image, the UITextField (only on tvOS?) by default has these behaviors:
A translucent overlay (make the background and the white text grey in the second button)
A white background and bigger size when it's focused (the first button)
How do I remove/change these behaviors?
What did I do?
I tried to change all color related property (except text color) in Interface Builder to Clear color
I used these code to build the view programmatically
let view = UITextField()
view.backgroundColor = .clear
view.translatesAutoresizingMaskIntoConstraints = false
view.font = view.font?.withSize(16)
view.textAlignment = .center
view.borderStyle = .none
view.tintColor = .clear
view.tintAdjustmentMode = .normal
view.accessibilityIgnoresInvertColors = true
view.textColor = .white
view.disabledBackground = .none
view.background = .none
view.layer.backgroundColor = CGColor(gray: 0.0, alpha: 0.0)
view.layer.shadowColor = CGColor(gray: 0.0, alpha: 0.0)
view.layer.borderColor = CGColor(gray: 0.0, alpha: 0.0)
view.layer.shadowOpacity = 0.0
Additional Information
A new tvOS app project, created with XCode 12.2 in macOS 10.15.7
Run on Apple TV simulator
No additional libraries/pods used

Actually we always can inherit UIKit classes and do whatever layout/style we want. Here is very raw demo of how this can be done.
Prepared & tested with Xcode 12.1 / tvOS 14.0
So just substitute custom subclass of UITextField class
class MyTextField: UITextField {
lazy var textLayer = CATextLayer()
override func didMoveToSuperview() {
super.didMoveToSuperview()
layer.backgroundColor = UIColor.clear.cgColor
textLayer.font = self.font
textLayer.fontSize = 36
textLayer.foregroundColor = UIColor.white.cgColor
textLayer.alignmentMode = .center
textLayer.frame = layer.bounds
layer.addSublayer(textLayer)
layer.borderWidth = 2
}
override func layoutSublayers(of layer: CALayer) {
layer.borderColor = self.isFocused ? UIColor.black.cgColor : UIColor.clear.cgColor
textLayer.frame = layer.bounds
textLayer.string = self.text?.isEmpty ?? true ? self.placeholder : self.text
}
override func addSubview(_ view: UIView) {
// blocks standard styling
}
}

Related

set background color to label swift

i hava a problem, i am tryinf to set background color to label, but it is not working
This is how i set label
private var imageLbel: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = UIFont(name: "Arial Rounded MT Bold", size: 25)
label.textAlignment = .center
label.backgroundColor = GradientColor.setGradient()
label.numberOfLines = 1
return label
}()
This is class for gradient
class GradientColor {
static func setGradient(uiView: UIView) -> UIColor {
let colorTop = UIColor.orange
let colorBottom = UIColor.systemOrange
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorTop, colorBottom]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.frame = uiView.bounds
uiView.layer.insertSublayer(gradientLayer, at: 0)
return gradientLayer
}
}
The backgroundColor property accepts a value of type UIColor to be assigned, but your implementation of the function setGradient(uiView:) is not returning a value with the correct type. Also, you are calling setGradient() without passing the uiView argument required. I don't think your code even compiles correctly.
The function setGradient(uiView:) appears to be creating a CAGradientLayer instance and inserting it as a sublayer of the input uiView. I do not think returning a UIColor is required.
I suggest removing the line label.backgroundColor = GradientColor.setGradient(). Then, remove -> UIColor from the signature of setGradient(uiView:) so that it doesn't return anything, and remove return gradientLayer.
After that, somewhere after the label is added to the view hierarchy, call setGradient(uiView:) passing it imageLbel. Maybe in viewDidLoad() like this:
override viewDidLoad() {
super.viewDidLoad()
GradientColor.setGradient(uiView: imageLbel)
}

How do I make a UICollectionView transparent?

I have tried virtually (literally?) everything to make a horizontal collection view transparent which is overlaid on a map view.
This is my collection view:
fileprivate let restaurantCollection : UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
let restaurant = UICollectionView(frame: .zero, collectionViewLayout: layout)
restaurant.decelerationRate = .fast
restaurant.backgroundView = nil
restaurant.layer.backgroundColor = UIColor.clear.cgColor
restaurant.backgroundColor = .clear
restaurant.translatesAutoresizingMaskIntoConstraints = false
restaurant.register(MapCell.self, forCellWithReuseIdentifier: "Cell")
return restaurant
}()
As you can see it has a clear background, clear layer and the background view is nil.
And the cell is transparent as well:
func setupView() {
contentView.backgroundColor = UIColor.clear.withAlphaComponent(0)
contentView.addSubview(cellBackground)
cellBackground.translatesAutoresizingMaskIntoConstraints = false
cellBackground.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
cellBackground.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
cellBackground.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
cellBackground.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
I also added a view to the cell "backgroundView" that's pinned with constant 0 to all sides. And this too is clear.
lazy var cellBackground : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width, height: 220))
view.clipsToBounds = true
view.backgroundColor = .clear
view.layer.backgroundColor = UIColor.clear.cgColor
return view
}()
And after all that effort, the collection view still has a white background
View hierarchy: Here is the view that is still white
You need to make sure that you are setting backgroundColor to clear
self.collectionView.backgroundColor = UIColor.clear
self.collectionView.backgroundView = UIView.init(frame: CGRect.zero)
For Modern List Layout CollectionViews:
UICollectionLayoutListConfiguration.backgroundColor = .clear
UICollectionViewListCell.backgroundConfiguration = .clear()

Adding UIView as a subview to a UIButton and bring it to front is not working properly

I have a UIButton, the background color is white.
#IBOutlet weak var buttonNewPost: UIButton! {
didSet {
buttonNewPost.layer.borderColor = UIColor(red:0.88, green:0.88, blue:0.88, alpha:1.0).cgColor
buttonNewPost.layer.cornerRadius = 5
buttonNewPost.backgroundColor = .white
}
}
I want to add an UIView to add a shadow to this rounded button:
let buttonShadow = UIView()
buttonShadow.frame.size.width = buttonNewPost.layer.bounds.width
buttonShadow.frame.size.height = buttonNewPost.layer.bounds.height
buttonShadow.backgroundColor = .clear
buttonShadow.dropShadowEdged = true
buttonShadow.isUserInteractionEnabled = false
buttonNewPost.addSubview(buttonShadow)
buttonShadow.bringSubviewToFront(buttonNewPost)
The result is like this:
Why is the UIButton not in the front with the white background color? When I change the backgroundcolor of the UIButton to blue:
Why is it like that? I just want a white button with a shadow
You can apply shadow directly to UIButton:-
#IBOutlet weak var Btn: UIButton! {
didSet {
Btn.layer.borderColor = UIColor(red:0.88, green:0.88, blue:0.88, alpha:1.0).cgColor
Btn.layer.cornerRadius = 5
Btn.backgroundColor = .white
}
}
Add below code to Viewdidload:-
Btn?.layer.borderColor = UIColor.black.cgColor
Btn?.layer.borderWidth = 1.0
Btn?.layer.cornerRadius = 20.0
Btn?.layer.shadowOpacity = 0.5
Btn?.layer.shadowColor = UIColor.red.cgColor
Btn?.layer.shadowRadius = 5.0
Btn?.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
After using this code you will get result like this

Button Border with Transparent Background in Swift

How can I make a UIButton border to look alike in the below image (the "Getting Started") button with a transparent background?
How should I achieve this using storyboard or how to do it programmatically?
Setting the backgroundColor to clearColor makes the button transparent.Try the code below for example. You can configure and vary the borderAlpha,cornerRadius and colours as your want.
let borderAlpha : CGFloat = 0.7
let cornerRadius : CGFloat = 5.0
button.frame = CGRectMake(100, 100, 200, 40)
button.setTitle("Get Started", forState: UIControlState.Normal)
button.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
button.backgroundColor = UIColor.clearColor()
button.layer.borderWidth = 1.0
button.layer.borderColor = UIColor(white: 1.0, alpha: borderAlpha).CGColor
button.layer.cornerRadius = cornerRadius
Swift 5
Similar to #rakeshbs, but in Swift 5:
let borderAlpha : CGFloat = 0.7
let cornerRadius : CGFloat = 5.0
self.frame = CGRect(x: 100, y: 100, width: 200, height: 40)
self.setTitle("Login", for: UIControl.State.normal)
self.setTitleColor(UIColor.white, for: UIControl.State.normal)
self.backgroundColor = UIColor.clear
self.layer.borderWidth = 1.0
self.layer.borderColor = UIColor(white: 1.0, alpha: borderAlpha).cgColor
self.layer.cornerRadius = cornerRadius
using Extension:
extension UIButton
{
func setUpLayer(sampleButton: UIButton?) {
sampleButton!.setTitle("GET STARTED", forState: UIControlState.Normal)
sampleButton?.tintColor = UIColor.whiteColor()
sampleButton!.frame = CGRect(x:50, y:500, width:170, height:40)
sampleButton!.layer.borderWidth = 1.0
sampleButton!.layer.borderColor = UIColor.whiteColor().colorWithAlphaComponent(0.5).CGColor
sampleButton!.layer.cornerRadius = 5.0
sampleButton!.layer.shadowRadius = 3.0
sampleButton!.layer.shadowColor = UIColor.whiteColor().CGColor
sampleButton!.layer.shadowOpacity = 0.3
}
}
Usage:
let sampleUIButton = UIButton()
sampleUIButton.setUpLayer(sampleUIButton)
self.view.addSubview(sampleUIButton)
Using Swift 3, for Storyboard, just add this subclass to your project, then in the Identity Inspector, make this the class for the UIButton on your storyboard. You should then be able to adjust the boarder color and width.
#IBDesignable class CustomButton: UIButton {
#IBInspectable var borderColor: UIColor = UIColor.white {
didSet {
layer.borderColor = borderColor.cgColor
}
}
#IBInspectable var borderWidth: CGFloat = 2.0 {
didSet {
layer.borderWidth = borderWidth
}
}
override public func layoutSubviews() {
super.layoutSubviews()
clipsToBounds = true
}
}

Add a blur effect to a UIButton

How can i make a button background get blurred?
Ill found out to get a blurred effect with this:
let blur = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
blur.frame = buttonForDisabling.frame
self.tableView.addSubview(blur)
This is working, but only makes a blur with the same frame as my button. I would like to have a button with a blurred background. Is that possible in iOS8?
If you are using a button with an image, bring the imageview to front:
buttonForDisabling.bringSubview(toFront: buttonForDisabling.imageView!)
or just use this extension:
import Foundation
import UIKit
extension UIButton
{
func addBlurEffect()
{
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blur.frame = self.bounds
blur.isUserInteractionEnabled = false
self.insertSubview(blur, at: 0)
if let imageView = self.imageView{
self.bringSubview(toFront: imageView)
}
}
}
This can be done by creating the blur as you did and inserting it below the titleLabel of the UIButton. It's important to disable user interaction in order to allow the touches to not be intercepted by the the visual effect view and forwarded to the button.
Swift 4.2:
let blur = UIVisualEffectView(effect: UIBlurEffect(style:
UIBlurEffect.Style.light))
blur.frame = buttonForDisabling.bounds
blur.isUserInteractionEnabled = false //This allows touches to forward to the button.
buttonForDisabling.insertSubview(blur, at: 0)
Used Sherwin's great answer, but it didn't quite work for me as I use auto layout and my frame was .zero while this code runs. So I modified the code to use auto-layout and this now works for me:
import Foundation
import UIKit
extension UIButton {
func addBlurEffect(style: UIBlurEffect.Style = .regular, cornerRadius: CGFloat = 0, padding: CGFloat = 0) {
backgroundColor = .clear
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: style))
blurView.isUserInteractionEnabled = false
blurView.backgroundColor = .clear
if cornerRadius > 0 {
blurView.layer.cornerRadius = cornerRadius
blurView.layer.masksToBounds = true
}
self.insertSubview(blurView, at: 0)
blurView.translatesAutoresizingMaskIntoConstraints = false
self.leadingAnchor.constraint(equalTo: blurView.leadingAnchor, constant: padding).isActive = true
self.trailingAnchor.constraint(equalTo: blurView.trailingAnchor, constant: -padding).isActive = true
self.topAnchor.constraint(equalTo: blurView.topAnchor, constant: padding).isActive = true
self.bottomAnchor.constraint(equalTo: blurView.bottomAnchor, constant: -padding).isActive = true
if let imageView = self.imageView {
imageView.backgroundColor = .clear
self.bringSubviewToFront(imageView)
}
}
}
Swift 5 version of #tuvok's excellent response. I've also updated it and added options to control various aspects such as:
• style: The blur style
• cornerRadius: Allows you to make it rounded or a circle
• padding: This is useful if you want to use a cornerRadius but you want to make the size of the button larger for hit-testing.
extension UIButton {
func addBlurEffect(style: UIBlurEffect.Style = .regular, cornerRadius: CGFloat = 0, padding: CGFloat = 0) {
backgroundColor = .clear
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: style))
blurView.frame = bounds.inset(by: UIEdgeInsets(horizontal: padding, vertical: padding))
blurView.isUserInteractionEnabled = false
blurView.backgroundColor = .clear
if cornerRadius > 0 {
blurView.layer.cornerRadius = cornerRadius
blurView.layer.masksToBounds = true
}
self.insertSubview(blurView, at: 0)
if let imageView = self.imageView{
imageView.backgroundColor = .clear
self.bringSubviewToFront(imageView)
}
}
}