Swift UITextView LayoutManager subclass - swift

I am trying to subclass a UITextView's layoutManager
But keep getting crashes. The examples I have been looking at are in Objective C, so I'm getting a bit confused to how I am supposed to change the layoutManager
Here is my code...
class TextWrapLayoutManager: NSLayoutManager {
override func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
self.enumerateLineFragments(forGlyphRange: NSMakeRange(0, self.numberOfGlyphs)) { (rect, usedRect, textContainer, glyphRange, Bool) in
let lineBoundingRect = self.boundingRect(forGlyphRange: glyphRange, in: textContainer)
let adjustedLineRect = lineBoundingRect.offsetBy(dx: origin.x + 5, dy: origin.y + 2)
let fillColorPath: UIBezierPath = UIBezierPath(roundedRect: adjustedLineRect, cornerRadius: 10)
UIColor.red.setFill()
fillColorPath.fill()
}
}
}
let textView = UITextView(frame: CGRect(x: 0, y: canvasView.center.y - 50, width: UIScreen.main.bounds.width, height: 130))
textView.textContainer.layoutManager = TextWrapLayoutManager()
textView.keyboardAppearance = .dark
textView.textAlignment = .center
textView.font = UIFont.attrctFont(ofSize: 32, weight: .bold)
textView.textColor = textColor
textView.layer.cornerRadius = 10
textView.layer.masksToBounds = true
textView.textContainerInset = UIEdgeInsets(top: 2, left: 5, bottom: 2, right: 5)
textView.tintColor = .white
textView.isScrollEnabled = false
textView.delegate = self
self.canvasView.addSubview(textView)
addGestures(view: textView)
textView.becomeFirstResponder()
Using...
textView.textContainer.layoutManager = TextWrapLayoutManager()
Compliles but crashes on the next line.
What is the correct way to Subclass UITextView's LayoutManager?
Thanks

Probably your var textContainer is nil.
Use this init
init(frame: CGRect, textContainer: NSTextContainer?)
passing a non nil textContainer.
After that you will be able to set your custom layoutManager

Related

Subclassing UITextField with other UI elements / Swift 5

Hello everyone!)
Need some help!)
I have custom text field with input limit which was in my view controller. If you look below, you will see that my text field has: UIView (underlayer with some borders), two UILabels (name label and counter label), and UITextField inside of UIView. Now I want to make UITextField subclass and configure my text field there with whole UI-es.
MARK: - I working without storyboards, the code only.
The question is, can I implement this in UITextField class?) Or maybe better to use UIView class?)
I experimented and tried to do it in TextField class, but stuck on UIView (underlayer), I can't make it behind my text field. I add a bit of code.)
Have you any ideas how to implement this in right way?)
Thanks for every answer!)
Example
Code...
UIViewController class
import UIKit
class ViewController: UIViewController {
var inputLimitTextField = InputLimitTextField(frame: CGRect(x: 45, y: 200, width: 300, height: 40))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(inputLimitTextField)
}
}
UITextField class
import UIKit
class InputLimitTextField: UITextField {
var underlayerView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
configureTextField()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configureTextField()
}
func configureTextField() {
backgroundColor = .purple
underlayerView.backgroundColor = .red
underlayerView.alpha = 0.5
addSubview(underlayerView)
underlayerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
underlayerView.topAnchor.constraint(equalTo: self.bottomAnchor),
underlayerView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
underlayerView.centerXAnchor.constraint(equalTo: self.centerXAnchor)
])
}
override func layoutSubviews() {
super.layoutSubviews()
underlayerView.frame = self.bounds
sendSubviewToBack(underlayerView)
}
}
Considering the fact that there is still no answer to my question that would solve this issue… Also, given that using subclasses is a pretty popular practice in programming... I didn't find a specific answer to such a question on the stack. That's why I decided to answer my own question. I hope my approach to solving the problem helps someone in the future...
Code...
UIViewController class...
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
private lazy var inputLimitTextField = InputLimitTextField()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(inputLimitTextField)
inputLimitTextFieldPosition()
}
private func inputLimitTextFieldPosition() {
inputLimitTextField.center.x = self.view.center.x
inputLimitTextField.center.y = self.view.center.y - 100
}
}
UITextField class...
import UIKit
class InputLimitTextField: UITextField, UITextFieldDelegate {
private lazy var nameLabel = UILabel()
private lazy var counterLabel = UILabel()
private let textLayer = CATextLayer()
private let padding = UIEdgeInsets(top: 0.5, left: 10, bottom: 0.5, right: 17)
private let purpleUIColor = UIColor(red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1.0)
private let purpleCGColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(),
components: [0.2849253164, 0.1806431101, 0.5, 1.0])
private let redUIColor = UIColor(red: 1, green: 0.1806431101, blue: 0.09760022642, alpha: 1)
private let redCGColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(),
components: [ 1, 0.1806431101, 0.09760022642, 1.0])
override init(frame: CGRect) {
super.init(frame: frame)
configureTextField()
configureNameLabel()
configureCunterLabel()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configureTextField()
configureNameLabel()
configureCunterLabel()
}
private func configureTextField() {
let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width - 25
let textFieldFrame = CGRect(x: 0, y: 0, width: screenWidth, height: 40)
frame = textFieldFrame
backgroundColor = .clear
textColor = purpleUIColor
font = UIFont(name: "Helvetica", size: 17)
placeholder = "Input limit"
textAlignment = .left
contentVerticalAlignment = .center
clearButtonMode = .always
autocorrectionType = .no
keyboardType = .default
returnKeyType = .done
delegate = self
textLayer.backgroundColor = UIColor.white.cgColor
textLayer.borderColor = purpleCGColor
textLayer.borderWidth = 1.2
textLayer.cornerRadius = 10
textLayer.frame = layer.bounds
layer.insertSublayer(textLayer, at: 0)
layer.shadowColor = .init(gray: 0.5, alpha: 0.5)
layer.shadowOpacity = 0.7
layer.shadowOffset = .init(width: 2, height: 2)
addSubview(nameLabel)
nameLabel.frame = CGRect(x: 12, y: -12, width: 55, height: 16)
addSubview(counterLabel)
counterLabel.frame = CGRect(x: screenWidth - 34, y: 9, width: 22, height: 22)
}
override internal func textRect(forBounds bounds: CGRect) -> CGRect {
let bounds = super.textRect(forBounds: bounds)
return bounds.inset(by: padding)
}
override internal func editingRect(forBounds bounds: CGRect) -> CGRect {
let bounds = super.editingRect(forBounds: bounds)
return bounds.inset(by: padding)
}
override internal func clearButtonRect(forBounds bounds: CGRect) -> CGRect {
let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width - 25
return CGRect(x: screenWidth - 70, y: 0, width: 40, height: 40)
}
private func enableUI() {
self.textLayer.borderColor = redCGColor
self.counterLabel.layer.borderColor = redCGColor
self.counterLabel.textColor = redUIColor
self.textColor = redUIColor
self.nameLabel.layer.borderColor = redCGColor
self.nameLabel.textColor = redUIColor
}
private func disableUI() {
self.textLayer.borderColor = purpleCGColor
self.counterLabel.layer.borderColor = purpleCGColor
self.counterLabel.textColor = purpleUIColor
self.textColor = purpleUIColor
self.nameLabel.layer.borderColor = purpleCGColor
self.nameLabel.textColor = purpleUIColor
}
func firstTenCharsColor(text: String) -> NSMutableAttributedString {
let characterCount = 10
let stringLength = text.utf16.count
let attributedString = NSMutableAttributedString(string: text)
if stringLength >= characterCount {
attributedString.addAttribute(.foregroundColor, value: #colorLiteral( red: 0.2849253164, green: 0.1806431101, blue: 0.5, alpha: 1), range: NSMakeRange(0, characterCount) )
}
return attributedString
}
private func updateUI(inputText: String?) {
guard let textCount = inputText?.count else { return }
guard let text = self.text else { return }
if (textCount <= 10){
self.counterLabel.text = "\(10 - textCount)"
disableUI()
} else if (textCount >= 10) {
self.counterLabel.text = "\(10 - textCount)"
enableUI()
self.attributedText = firstTenCharsColor(text: text)
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = self.text, let textRange = Range(range, in: text) else { return true }
let updatedText = text.replacingCharacters(in: textRange, with: string)
self.updateUI(inputText: updatedText)
return true
}
func textFieldShouldClear(_ textField: UITextField) -> Bool {
self.textLayer.borderColor = purpleCGColor
self.counterLabel.text = "10"
disableUI()
return true
}
private func configureNameLabel() {
nameLabel.backgroundColor = .white
nameLabel.layer.cornerRadius = 3
nameLabel.layer.borderWidth = 1.2
nameLabel.layer.borderColor = purpleCGColor
nameLabel.layer.masksToBounds = true
nameLabel.font = UIFont(name: "Helvetica", size: 11)
nameLabel.text = "Input limit"
nameLabel.textAlignment = .center
nameLabel.textColor = purpleUIColor
}
private func configureCunterLabel() {
counterLabel.backgroundColor = .white
counterLabel.layer.cornerRadius = 5
counterLabel.layer.borderWidth = 1.2
counterLabel.layer.borderColor = purpleCGColor
counterLabel.layer.masksToBounds = true
counterLabel.font = UIFont(name: "Helvetica", size: 12)
counterLabel.text = "10"
counterLabel.textAlignment = .center
counterLabel.textColor = purpleUIColor
}
}
You can use it for any iPhone...
Stay safe and good luck! :)

Views misplaced when setting frames

I am trying to make a view programatically, making a card with an image and some text and overlaying it with some color. I have turned off clip to bounds and added some colors to make it more visual.
So when I set
overlay.frame = self.frame
or
overlay.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
the overlay should cover the entire view but it does not, why is this?
This is what is showing
This is what I want to see, but with each card having a blue layer on top
private var leftImage: UIImageView = {
let i = UIImageView(frame: .zero)
i.contentMode = .scaleAspectFill
i.image = UIImage()
return i
}()
private var topLabel: UILabel = {
let label = UILabel(frame: .zero)
label.isUserInteractionEnabled = false
label.font = UIFont.boldSystemFont(ofSize: 16.0)
label.lineBreakMode = .byWordWrapping
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 2
return label
}()
var bottomLabel: UILabel = {
let label = UILabel(frame: .zero)
label.isUserInteractionEnabled = false
label.lineBreakMode = .byWordWrapping
label.font = UIFont.systemFont(ofSize: 12.0)
label.numberOfLines = 1
label.text = "60 seconds"
return label
}()
private var stackView: UIStackView = {
let stack = UIStackView(frame: .zero)
stack.axis = .vertical
stack.isUserInteractionEnabled = false
stack.distribution = .fillEqually
stack.layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
stack.isLayoutMarginsRelativeArrangement = true
return stack
}()
private var overlay: UIView = {
let view = UIView(frame: .zero)
view.backgroundColor = .blue
view.alpha = 0.8
//view.isHidden = true
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
create()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
create()
}
private func create() {
self.translatesAutoresizingMaskIntoConstraints = false
//leftview
leftImage.frame = CGRect(x: 0, y: 0, width: frame.width / 2, height: frame.height)
addSubview(leftImage)
//rightVIew
stackView.frame = CGRect(x: frame.midX, y: 0, width: frame.width / 2, height: frame.height)
clipsToBounds = false
//add views to stack
stackView.addArrangedSubview(topLabel)
stackView.addArrangedSubview(bottomLabel)
addSubview(stackView)
overlay.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
addSubview(overlay)
//card styling
layer.cornerRadius = 10
}
overlay.frame = self.frame
That can never be right, except by accident, because the frame of overlay and the frame of self are in two different coordinate systems. At the very least you want to say
overlay.frame = self.bounds // bounds, not frame
However, that isn't going to work either unless you say it in the right place. The right place is when layout occurs:
override func layoutSubviews() {
super.layoutSubviews()
self.overlay.frame = self.bounds
}
Simply adding that to your existing code should solve the problem.
The issue is that you're setting your overlay's dimensions like so:
overlay.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
before the superview has determined its final width and height. You'll need to do one of the following:
Call create() after the superview class has determined its final size
Continuously set the overlay's frame as the superview's width and height changes (see https://developer.apple.com/documentation/uikit/uiview/1622482-layoutsubviews)
Use AutoLayout constraints via a xib/storyboard file

Is possible make a UITextField like this?

Situation: I want to use a custom UITextField class for my textField in a xcode project.
I want to the textField look like this:
I had no problems in making the edges rounded, and change the color of my placeholder, but I have no idea how to keep the bottom edges flat and draw a black border only on the bottom.
This is my code:
import UIKit
class GrayTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
backgroundColor = .grayf1f1f1
layer.borderWidth = 1
layer.borderColor = UIColor.black.cgColor
layer.cornerRadius = 10
clipsToBounds = true
}
override var placeholder: String? {
didSet {
let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .thin)]
attributedPlaceholder = NSAttributedString(string: placeholder ?? "", attributes: attributes)
}
}
}
And my current result:
In your answer, still there is some issue in bottom left and right corner.
To achieve exact result, change your UITextField Border Style to No Border.
Padding for Text:
class GrayTextField: UITextField {
let padding = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 5)
..... Your Exact Code .....
override open func textRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}
override open func placeholderRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}
override open func editingRect(forBounds bounds: CGRect) -> CGRect {
return bounds.inset(by: padding)
}
}
OutPut
Well, after some researching, i do it.
Here if my final code:
import UIKit
class GrayTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
backgroundColor = .grayf1f1f1
clipsToBounds = true
let maskPath = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.topLeft, .topRight],
cornerRadii: CGSize(width: 10.0, height: 10.0))
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
layer.mask = shape
addBottomBorder(with: .darkGray, andWidth: 1)
}
override var placeholder: String? {
didSet {
let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.black, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .thin)]
attributedPlaceholder = NSAttributedString(string: placeholder ?? "", attributes: attributes)
}
}
func addBottomBorder(with color: UIColor?, andWidth borderWidth: CGFloat) {
let border = UIView()
border.backgroundColor = color
border.autoresizingMask = [.flexibleWidth, .flexibleTopMargin]
border.frame = CGRect(x: 0, y: frame.size.height - borderWidth, width: frame.size.width, height: borderWidth)
addSubview(border)
}
}
And this is the result:

What is the best way to auto-resize a UIButton based on its contents, mainly its title and image?

I have written the below code in order to generate a custom UIButton, which I intend to use in different locations across my applications:
import UIKit
import ChameleonFramework
class CustomButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
convenience init(buttonTitleTexForNormalState titleForNormalState: String, buttonTitleTextColourForNormalState normalTextColour: UIColor, buttonTitleTextColourForHighlightedState highlightedTextColour: UIColor, buttonTitleFontType fontType: String, buttonTitleFontSize fontSize: CGFloat, buttonBackgroundHexColourCode hexColour: String, buttonFrameCornerRadius cornerRadius: CGFloat, buttonFrameBorderWidth borderWidth: CGFloat, buttonFrameBorderColour borderColour: String, buttonBackgroundTransperancyAlphaValue transperancy: CGFloat, buttonTagNumber tagValue: Int, buttonTarget: Any?, buttonSelector: Selector, buttonImageForNormalState normalButtonImage: String) {
self.init()
setupButtonEssentials(buttonTitleTexForNormalState: titleForNormalState, buttonTitleTextColourForNormalState: normalTextColour, buttonTitleTextColourForHighlightedState: highlightedTextColour, buttonTitleFontType: fontType, buttonTitleFontSize: fontSize, buttonBackgroundHexColourCode: hexColour, buttonFrameCornerRadius: cornerRadius, buttonFrameBorderWidth: borderWidth, buttonFrameBorderColour: borderColour, buttonBackgroundTransperancyAlphaValue: transperancy, buttonTagNumber: tagValue, buttonTarget: buttonTarget, buttonSelector: buttonSelector, buttonImageForNormalState: normalButtonImage)
}
func setupButtonEssentials(buttonTitleTexForNormalState titleForNormalState: String, buttonTitleTextColourForNormalState normalTextColour: UIColor, buttonTitleTextColourForHighlightedState highlightedTextColour: UIColor, buttonTitleFontType fontType: String, buttonTitleFontSize fontSize: CGFloat, buttonBackgroundHexColourCode hexColour: String, buttonFrameCornerRadius cornerRadius: CGFloat, buttonFrameBorderWidth borderWidth: CGFloat, buttonFrameBorderColour borderColour: String, buttonBackgroundTransperancyAlphaValue transperancy: CGFloat, buttonTagNumber tagValue: Int, buttonTarget: Any?, buttonSelector: Selector, buttonImageForNormalState normalButtonImage: String) {
setTitleColor(normalTextColour, for: .normal)
setTitleColor(highlightedTextColour, for: .highlighted)
titleLabel?.font = UIFont(name: fontType, size: fontSize)
setTitle(titleForNormalState, for: .normal)
backgroundColor = UIColor(hexString: hexColour)
layer.cornerRadius = cornerRadius
layer.borderWidth = borderWidth
layer.borderColor = UIColor(hexString: borderColour)?.cgColor
showsTouchWhenHighlighted = true
alpha = transperancy
contentHorizontalAlignment = .center
self.tag = tagValue
addTarget(target, action: buttonSelector, for: .touchUpInside)
if let buttonImage = UIImage(named: normalButtonImage) {
setImage(buttonImage.withRenderingMode(.alwaysOriginal), for: .normal)
contentMode = .scaleAspectFit
}
setShadow()
translatesAutoresizingMaskIntoConstraints = false
}
private func setShadow() {
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0.0, height: 6.0)
layer.shadowRadius = 8
layer.shadowOpacity = 0.5
clipsToBounds = true
layer.masksToBounds = false
}
func shake() {
let shake = CABasicAnimation(keyPath: "position")
shake.duration = 0.1
shake.repeatCount = 2
shake.autoreverses = true
let fromPoint = CGPoint(x: center.x-8, y: center.y)
let fromValue = NSValue(cgPoint: fromPoint)
let toPoint = CGPoint(x: center.x+8, y: center.y)
let toValue = NSValue(cgPoint: toPoint)
shake.fromValue = fromValue
shake.toValue = toValue
layer.add(shake, forKey: "position")
}
}
And the below code illustrates an example of where I created an instance from the custom UIButton class (as demonstrated above) inside a ViewController:
import UIKit
import ChameleonFramework
class MainScreen: UIViewController, UINavigationBarDelegate {
var newFileButton = CustomButton(buttonTitleTexForNormalState: "New...", buttonTitleTextColourForNormalState: .black, buttonTitleTextColourForHighlightedState: .blue, buttonTitleFontType: "Apple SD Gothic Neo", buttonTitleFontSize: 17, buttonBackgroundHexColourCode: "#B24B32", buttonFrameCornerRadius: 25, buttonFrameBorderWidth: 2, buttonFrameBorderColour: "#7AFFD2", buttonBackgroundTransperancyAlphaValue: 0.75, buttonTagNumber: 1, buttonTarget: self, buttonSelector: #selector(buttonPressed(sender:)), buttonImageForNormalState: "New File")
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print("viewDidLayoutSubviews")
view.addSubview(newFileButton)
newFileButton.frame.size.width = 140
newFileButton.frame.size.height = 100
}
#objc func buttonPressed(sender : UIButton) {
if sender.tag == 1 {
newFileButton.shake()
guard let nextViewControllerToGoTo = storyboard?.instantiateViewController(withIdentifier: "NewFileButtonPressedTabController") else {
print("NewFileButtonPressedTabController could not be presented")
return
}
present(nextViewControllerToGoTo, animated: true, completion: nil)
}
}
However, as it can be seen from the above code, I ended up defining the size of the custom UIButton in terms of its width and height manually.
I wonder if there is a way for Xcode to figure out the best width and height for each custom UIButton based on its contents, mainly its title and image?
P.S: I tried to use intrinsicContent, however, it did not work out for me. Any suggestions are much appreciated.
Thanks,
Shadi.
Remove the code that sets newFileButton.frame.size.width and .height, and it should take on the content size of whatever titles/images you add to it - but only at a minimum. If you want it to be any bigger than that, just set content insets (sort of like padding around the content).
In your button's class:
self.contentEdgeInsets = UIEdgeInsets(top: 10, left: 30, bottom: 10, right: 20)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -20, bottom: 0, right: 0)

Swift - Customizing UISearchBar design programmatically

I'm trying to customize UISearchBar design programmatically. I tried adding a bunch of codes but only a few places are changed.
This is the design I want to create.
And this is how it looks now.
I screen-captured the second image from the simulator so it's bigger.
Anyways, I'm trying to make my search bar has
Lighter background color
Shorter textfield in height
Textfield to have less corner radious
Here are my codes:
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 60))
[In viewDidLoad()]
searchBar.delegate = self
searchBar.isTranslucent = false
searchBar.placeholder = "Search the phrase"
searchBar.tintColor = UIColor(red:0.73, green:0.76, blue:0.78, alpha:1.0)
searchBar.setImage(UIImage(named: "search"), for: .search, state: .normal)
let forTextField = searchBar.value(forKey: "searchField") as? UITextField
forTextField?.textColor = UIColor(red:0.31, green:0.31, blue:0.31, alpha:1.0)
forTextField?.font = UIFont(name: "HelveticaNeue-Light", size: 14)
forTextField?.clipsToBounds = true
forTextField?.layer.cornerRadius = 5
forTextField?.frame.size.height = 30
I would appreciate your help!
Here is the way you can achieve that:
class ViewController: UIViewController, UISearchBarDelegate {
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: 60))
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
searchBar.isTranslucent = false
searchBar.placeholder = "Search the phrase"
searchBar.tintColor = UIColor(red:0.73, green:0.76, blue:0.78, alpha:1.0)
//1. Lighter background color
searchBar.barTintColor = UIColor(netHex: 0xE6E6E6)
self.view.addSubview(searchBar)
}
override func viewDidAppear(_ animated: Bool) {
for subView in searchBar.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
var bounds: CGRect
bounds = textField.frame
//2. Shorter textfield in height
bounds.size.height = 28
textField.bounds = bounds
//3. Textfield to have less corner radious
textField.layer.cornerRadius = 5 //Probably you can play with this and see the changes.
textField.clipsToBounds = true
}
}
}
}
}
extension UIColor {
convenience init(r: Int, g: Int, b: Int, a: Int = 255) {
self.init(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(a) / 255.0)
}
convenience init(netHex:Int) {
self.init(r:(netHex >> 16) & 0xff, g:(netHex >> 8) & 0xff, b:netHex & 0xff)
}
}