Put two (side by side) buttons as a right side overlay of an UITextField - ios

(Swift3/iOS10)
I'm trying to put two buttons (save/cancel) inside of a UITextField using the rightView property. My basic setup code (called from viewDidLoad) is as follows:
private func accesorizeRenameField() {
let saveButton = UIButton(type: .system)
saveButton.setImage(#imageLiteral(resourceName: "buttonCheckmark"), for: .normal)
saveButton.addTarget(self, action: #selector(renameSave), for: .touchUpInside)
saveButton.tintColor = UIColor(white: 0.15, alpha: 1)
let cancelButton = UIButton(type: .system)
cancelButton.setImage(#imageLiteral(resourceName: "buttonX"), for: .normal)
cancelButton.addTarget(self, action: #selector(renameCancel), for: .touchUpInside)
cancelButton.tintColor = UIColor(227, 34, 60, 1)
let container = UIView()
container.addSubview(saveButton)
container.addSubview(cancelButton)
container.translatesAutoresizingMaskIntoConstraints = false
container.backgroundColor = UIColor.cyan
saveButton.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
cancelButton.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
saveButton.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true
cancelButton.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true
saveButton.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
saveButton.trailingAnchor.constraint(equalTo: container.centerXAnchor).isActive = true
cancelButton.leadingAnchor.constraint(equalTo: container.centerXAnchor).isActive = true
cancelButton.trailingAnchor.constraint(equalTo: container.trailingAnchor).isActive = true
self.renameField.rightView = container
self.renameField.rightViewMode = .always
}
Later on, when I expose the rename field through some animation, I call
self.renameField.rightView?.bounds = CGRect(x: 0, y: 0, width: self.renameField.bounds.height * 2, height: self.renameField.bounds.height)
self.renameField.rightView?.setNeedsLayout()
"rightView.frame \(self.renameField.rightView?.frame)".print()
self.renameField.rightView?.subviews.enumerated().forEach() {index,child in
"child \(index) frame \(child.frame)".print()
}
However, I cannot get the buttons to show up. The cyan background (for debugging) shows up, but actually is square (it should be a 2:1 rectangle). The print shows that the subviews have frames of size 0. What is the right/idiomatic way to do this? I feel like I'm just throwing hammers here...

Create UIButton as type of .custom instead of .system.
And as you already know renameField's height in viewDidLoad, you don't need to bother with constraint.
The code below is enough.
override func
viewDidLoad() {
super.viewDidLoad()
let wSize = renameField.frame.size.height - 2
let saveButton = UIButton( type: .custom )
saveButton.setImage( #imageLiteral(resourceName: "buttonCheckmark"), for: .normal )
saveButton.addTarget( self, action: #selector(renameSave), for: .touchUpInside )
saveButton.frame = CGRect( x: 0, y: 0, width: wSize, height: wSize )
let cancelButton = UIButton( type: .custom )
cancelButton.setImage( #imageLiteral(resourceName: "buttonX"), for: .normal )
cancelButton.addTarget( self, action: #selector(renameCancel), for: .touchUpInside )
cancelButton.frame = CGRect( x: wSize, y: 0, width: wSize, height: wSize )
let wV = UIView()
wV.frame = CGRect( x:0, y:0, width: wSize * 2, height: wSize )
wV.addSubview( saveButton )
wV.addSubview( cancelButton )
renameField.rightView = wV;
renameField.rightViewMode = .always;
}

Related

The size of the UIButton doesn't change - Swift

I'm trying to setup the custom navigation bar in my iOS app, but .frame = CGRect(...) doesn't change the size of buttons that I added to it. Buttons appeared inside the navigation bar, but they have wrong size, or maybe constraints, I don't know.
// Setting up the Navigation Bar
private func setupNavigationBar() {
// Remove the shadow under the Navigation Bar
self.navigationController?.navigationBar.shadowImage = UIImage()
let addButton = UIButton(type: .system)
addButton.setImage(UIImage(named: "ic_add")?.withRenderingMode(.alwaysOriginal), for: .normal)
addButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
let settingsButton = UIButton(type: .system)
settingsButton.setImage(UIImage(named: "ic_settings")?.withRenderingMode(.alwaysOriginal), for: .normal)
settingsButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: settingsButton), UIBarButtonItem(customView: addButton)]
}
(I call this function inside the viewDidLoad())
Here you can see the result on my iPhone:
This is work for me. Please try it. (iOS 11)
private func setupNavigationBar() {
// Remove the shadow under the Navigation Bar
self.navigationController?.navigationBar.shadowImage = UIImage()
let addButton = UIButton(type: .custom)
addButton.setImage(UIImage(named: "ic_add")?.withRenderingMode(.alwaysOriginal), for: .normal)
addButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
let settingsButton = UIButton(type: .custom)
settingsButton.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
settingsButton.setImage(UIImage(named: "ic_settings")?.withRenderingMode(.alwaysOriginal), for: .normal)
let menuBarItem = UIBarButtonItem(customView: settingsButton) // new line
let currWidth = menuBarItem.customView?.widthAnchor.constraint(equalToConstant: 10) // new line
currWidth?.isActive = true // new line
let currHeight = menuBarItem.customView?.heightAnchor.constraint(equalToConstant: 10) // new line
currHeight?.isActive = true // new line
navigationItem.rightBarButtonItems = [
menuBarItem, // modify
UIBarButtonItem(customView: addButton)]
}
Try to change the button type
Replace .system to .custom .
Also check the size of original image if it is very large.

Adding multiple UIButton to multiple UIView in Swift

I have written code below that programmatically creates multiple UIButton that are placed on different UIView. All buttons are similar and different by button title. The code does accomplish what it needs to do, but as you can see, the code is rather verbose, it's too lengthy.
Question
How can I structure the code below and make it compact and succinct?
Code
let myButton0 = UIButton(type: UIButtonType.Custom)
myButton0.setTitle("Text 0", forState:.Normal)
myButton0.titleLabel!.font = UIFont.systemFontOfSize(12)
myButton0.setTitleColor(UIColor.whiteColor(), forState: .Normal)
myButton0.backgroundColor = UIColor.darkGrayColor()
myButton0.frame = CGRectMake(0, 0, 200, 100)
myButton0.alpha = 1
myButton0.showsTouchWhenHighlighted = false
myButton0.adjustsImageWhenHighlighted = false
myButton0.addTarget(self, action: #selector(ViewController.goDoThis0), forControlEvents:.TouchUpInside)
myView0.addSubview(myButton0)
let myButton1 = UIButton(type: UIButtonType.Custom)
myButton1.setTitle("Text 1", forState:.Normal)
myButton1.titleLabel!.font = UIFont.systemFontOfSize(12)
myButton1.setTitleColor(UIColor.whiteColor(), forState: .Normal)
myButton1.backgroundColor = UIColor.darkGrayColor()
myButton1.frame = CGRectMake(0, 0, 200, 100)
myButton1.alpha = 1
myButton1.showsTouchWhenHighlighted = false
myButton1.adjustsImageWhenHighlighted = false
myButton1.addTarget(self, action: #selector(ViewController.goDoThis1), forControlEvents:.TouchUpInside)
myView1.addSubview(myButton1)
let myButton2 = UIButton(type: UIButtonType.Custom)
myButton2.setTitle("Text 2", forState:.Normal)
myButton2.titleLabel!.font = UIFont.systemFontOfSize(12)
myButton2.setTitleColor(UIColor.whiteColor(), forState: .Normal)
myButton2.backgroundColor = UIColor.darkGrayColor()
myButton2.frame = CGRectMake(0, 0, 200, 100)
myButton2.alpha = 1
myButton2.showsTouchWhenHighlighted = false
myButton2.adjustsImageWhenHighlighted = false
myButton2.addTarget(self, action: #selector(ViewController.goDoThis2), forControlEvents:.TouchUpInside)
myView2.addSubview(myButton2)
let myButton3 = UIButton(type: UIButtonType.Custom)
myButton3.setTitle("Text 3", forState:.Normal)
myButton3.titleLabel!.font = UIFont.systemFontOfSize(12)
myButton3.setTitleColor(UIColor.whiteColor(), forState: .Normal)
myButton3.backgroundColor = UIColor.darkGrayColor()
myButton3.frame = CGRectMake(0, 0, 200, 100)
myButton3.alpha = 1
myButton3.showsTouchWhenHighlighted = false
myButton3.adjustsImageWhenHighlighted = false
myButton3.addTarget(self, action: #selector(ViewController.goDoThis3), forControlEvents:.TouchUpInside)
myView3.addSubview(myButton3)
let myButton4 = UIButton(type: UIButtonType.Custom)
myButton4.setTitle("Text 4", forState:.Normal)
myButton4.titleLabel!.font = UIFont.systemFontOfSize(12)
myButton4.setTitleColor(UIColor.whiteColor(), forState: .Normal)
myButton4.backgroundColor = UIColor.darkGrayColor()
myButton4.frame = CGRectMake(0, 0, 200, 100)
myButton4.alpha = 1
myButton4.showsTouchWhenHighlighted = false
myButton4.adjustsImageWhenHighlighted = false
myButton4.addTarget(self, action: #selector(ViewController.goDoThis4), forControlEvents:.TouchUpInside)
myView4.addSubview(myButton4)
(Swift 4.0)
First, write a common method for creating button:
func createButton(title:String,toView:UIView,action:Selector) {
let myButton = UIButton(type: UIButtonType.custom)
myButton.setTitle(title, for:.normal)
myButton.titleLabel?.font = UIFont.systemFont(ofSize: 12)
myButton.setTitleColor(UIColor.white, for: .normal)
myButton.backgroundColor = UIColor.darkGray
myButton.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
myButton.alpha = 1
myButton.showsTouchWhenHighlighted = false
myButton.adjustsImageWhenHighlighted = false
myButton.addTarget(self, action: action, for: .touchUpInside)
toView.addSubview(myButton)
}
Then create buttons like this:
let buttonInfos = [
["Text 0",myView0,#selector(ViewController.goDoThis0)],
["Text 1",myView1,#selector(ViewController.goDoThis1)],
["Text 2",myView2,#selector(ViewController.goDoThis2)],
["Text 3",myView3,#selector(ViewController.goDoThis3)],
["Text 4",myView4,#selector(ViewController.goDoThis4)],
]
for buttonInfo in buttonInfos {
self.createButton(title: buttonInfo[0] as! String, toView: buttonInfo[1] as! UIView, action: buttonInfo[2] as! Selector)
}
While this question has already been answered, I would like to contribute another approach adapted from Yun CHEN's answer.
Similarly, create a common method for your buttons:
func createButton(title:String,toView:UIView,action:Selector) {
let myButton = UIButton(type: UIButtonType.custom)
myButton.setTitle(title, for:.normal)
myButton.titleLabel?.font = UIFont.systemFont(ofSize: 12)
myButton.setTitleColor(UIColor.white, for: .normal)
myButton.backgroundColor = UIColor.darkGray
myButton.frame = CGRect(x: 0, y: 0, width: 200, height: 100)
myButton.alpha = 1
myButton.showsTouchWhenHighlighted = false
myButton.adjustsImageWhenHighlighted = false
myButton.addTarget(self, action: action, for: .touchUpInside)
toView.addSubview(myButton)
}
Then list out the button information in an array of tuples:
let buttonInfos = [
("Text 0",myView0,#selector(ViewController.goDoThis0)),
("Text 1",myView1,#selector(ViewController.goDoThis1)),
("Text 2",myView2,#selector(ViewController.goDoThis2)),
("Text 3",myView3,#selector(ViewController.goDoThis3)),
("Text 4",myView4,#selector(ViewController.goDoThis4)),
]
And finally create the buttons like so:
for buttonInfo in buttonInfos {
self.createButton(title: buttonInfo.0, toView: buttonInfo.1, action: buttonInfo.2)
}
As you can see in your case, by using tuples, you do not need to cast the types with as! String , as! UIView etc, simplifying and making the code shorter and safer.

RightBarButtonItems won't be shown anymore on iOS 11

The function self.navigationItem.rightBarButtonItem = cartBarButton won't show my item on the right of UINavigationController's NavBar
EDIT
let cartOriginalImage = UIImage.cart
let cartButton = UIImageButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
cartButton.setBackgroundImage(cartOriginalImage, for: .normal)
cartButton.tintColor = Colors.Navigation.Tint.default
cartButton.addTarget(self, action: #selector(MainViewController.cartButtonPressedInHomePage(sender:)), for: .touchUpInside)
let cartBarButton = UIBarButtonItem(customView: cartButton)
if let badge = badge {
cartBarButton.badgeValue = badge
cartBarButton.badge.backgroundColor = Colors.Navigation.Background.badge
cartBarButton.badge.textColor = Colors.Navigation.Text.badge
}
I had the similar issue with custom image view. My suggestion is to wrap your custom view into container view.
private func configureUserAvatarView() {
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(avatarViewAction(_:)))
let customView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
customView.addGestureRecognizer(tapRecognizer)
let imageView = FUIImageView(image: #imageLiteral(resourceName: "avatar_default_30х30"))
imageView.isCircular = true
imageView.contentMode = .scaleAspectFit
imageView.frame = customView.bounds
customView.addSubview(imageView)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: customView)
}

Hiding and showing (subviews) button or change title?

I have a problem with my subviews. I have 2 visible buttons and 1 which should show after click the first one. More Precisely, i have Start Button, Reset Button and Stop Button. On load should show just Start and Reset button, but when I press Start Button the Reset button should hide and stop button should show. Syntax like isHidden doesn't works. What is the problem?
Star, Stop and Reset Button:
var stopButton: UIButton{
let stopButton = UIButton(frame: CGRect(x: 220, y: 50, width: 100, height: 100))
stopButton.backgroundColor = .white
stopButton.setTitle("Stop", for: .normal)
stopButton.addTarget(self, action: #selector(stopButtonAction), for: .touchUpInside)
stopButton.layer.cornerRadius = 50
stopButton.layer.masksToBounds = true
stopButton.isHidden = true
return stopButton
}
var resetButton: UIButton{
let resetButton = UIButton(frame: CGRect(x: 220, y: 50, width: 100, height: 100))
resetButton.backgroundColor = .red
resetButton.setTitle("Reset", for: .normal)
resetButton.addTarget(self, action: #selector(resetButtonAction), for: .touchUpInside)
resetButton.layer.cornerRadius = 50
resetButton.layer.masksToBounds = true
return resetButton
}
var startButton: UIButton{
let startButton = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
startButton.backgroundColor = .green
startButton.setTitle("Start", for: .normal)
startButton.addTarget(self, action: #selector(startButtonAction), for: .touchUpInside)
startButton.layer.cornerRadius = 50
startButton.layer.masksToBounds = true
return startButton
}
Here i add this Subviews(this func also add UIView and it's called in viewDidLoad):
func addBottomView()
{
let orginX = (collectionView?.frame.minX)!
let orginY = (collectionView?.frame.maxY)!
let heightOfView = view.frame.height - (view.frame.height / 100) * 70
let bottomView = UIView(frame: CGRect(x: orginX, y: orginY, width: view.frame.width, height: heightOfView))
bottomView.backgroundColor = .orange
view.addSubview(bottomView)
bottomView.addSubview(stopButton)
bottomView.addSubview(startButton)
bottomView.addSubview(resetButton)
}
And here are my functions which are connected to this buttons:
func startButtonAction()
{
blinkAction()
print("START ACTION")
resetButton.isHidden = true
stopButton.isHidden = false
view.layoutSubviews()
}
func resetButtonAction()
{
print("RESET ACTION")
blinkAction()
}
func stopButtonAction()
{
print("STOP ACTION")
blinkAction()
resetButton.isHidden = false
stopButton.isHidden = true
view.layoutSubviews()
}
I add layoutSubviews method but it don't help. I also tried use self before name of button which is hidden but i also doesn't work. Any advice?
You can create button using computed properties with lazy keywoard
lazy var stopButton: UIButton = {
let stopButton = UIButton(frame: CGRect(x: 220, y: 50, width: 100, height: 100))
stopButton.backgroundColor = .yellow
stopButton.setTitle("Stop", for: .normal)
stopButton.addTarget(self, action: #selector(stopButtonAction), for: .touchUpInside)
stopButton.layer.cornerRadius = 50
stopButton.isHidden = true
stopButton.layer.masksToBounds = true
return stopButton
}()
lazy var resetButton: UIButton = {
let resetButton = UIButton(frame: CGRect(x: 220, y: 50, width: 100, height: 100))
resetButton.backgroundColor = .red
resetButton.setTitle("Reset", for: .normal)
resetButton.addTarget(self, action: #selector(resetButtonAction), for: .touchUpInside)
resetButton.layer.cornerRadius = 50
resetButton.layer.masksToBounds = true
return resetButton
}()
lazy var startButton: UIButton = {
let startButton = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
startButton.backgroundColor = .green
startButton.setTitle("Start", for: .normal)
startButton.addTarget(self, action: #selector(startButtonAction), for: .touchUpInside)
startButton.layer.cornerRadius = 50
startButton.layer.masksToBounds = true
return startButton
}()
The computed properties startButton, stopButton, resetButton are not the SAME items as the ones added as subviews. Computed properties do not store a value, they give you methods to get values and set changes. So the actions you take there with isHidden do not apply to your view.
The reason of isHidden property not working well is that when your computed property variable you get a new instance of UIButton rather than old one. If you want to want to use computed properties then you should create lazy properties. So whenever you call property variable you'll get old one instance of UIButton.
Your properties always create new buttons, so your references will not be the same. When you set the isHidden, your button will be re-created so you set the isHidden propery of another button that is not added to bottomView.
Just use plain properties:
var stopButton: UIButton!
var resetButton: UIButton!
var startButton: UIButton!
Create the buttons:
func createButtons() {
let stopButton = UIButton(frame: CGRect(x: 220, y: 50, width: 100, height: 100))
stopButton.backgroundColor = .white
stopButton.setTitle("Stop", for: .normal)
stopButton.addTarget(self, action: #selector(stopButtonAction), for: .touchUpInside)
stopButton.layer.cornerRadius = 50
stopButton.layer.masksToBounds = true
stopButton.isHidden = true
let resetButton = UIButton(frame: CGRect(x: 220, y: 50, width: 100, height: 100))
resetButton.backgroundColor = .red
resetButton.setTitle("Reset", for: .normal)
resetButton.addTarget(self, action: #selector(resetButtonAction), for: .touchUpInside)
resetButton.layer.cornerRadius = 50
resetButton.layer.masksToBounds = true
let startButton = UIButton(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
startButton.backgroundColor = .green
startButton.setTitle("Start", for: .normal)
startButton.addTarget(self, action: #selector(startButtonAction), for: .touchUpInside)
startButton.layer.cornerRadius = 50
startButton.layer.masksToBounds = true
}
Add as subviews:
bottomView.addSubview(stopButton)
bottomView.addSubview(startButton)
bottomView.addSubview(resetButton)
And use them:
resetButton.isHidden = false
stopButton.isHidden = true

modal segue slow first time when triggered

I've created a modal segue to a viewController, however when i trigger this segue, there seem to be some delay when viewing the viewController. All i have in the viewController is in the viewDidLoad. what could course this slow modal segue?
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Caption".uppercaseString
self.view.backgroundColor = UIColor(hexString: "#0B1E30")
self.navigationController?.navigationBar.barTintColor = UIColor(gradientStyle: UIGradientStyle.LeftToRight, withFrame: CGRectMake(0, 0, self.view.frame.width, (self.navigationController?.navigationBar.frame.height)! + 20), andColors: [UIColor(hexString: "#7F5CE6"), UIColor(hexString: "#9D8FE2")])
let closeButton = UIBarButtonItem(image: UIImage(named: "Cross"), style: UIBarButtonItemStyle.Done, target: self, action: "dismissController")
self.navigationItem.leftBarButtonItem = closeButton
textView?.text = "Add caption (optional)"
textView?.becomeFirstResponder()
textView?.keyboardAppearance = UIKeyboardAppearance.Dark
textView?.font = UIFont(name: "Montserrat-Light", size: 13)
textView?.textColor = UIColor(hexString: "#363636")
capturedImageView = UIImageView(image: capturedPhoto)
capturedImageView?.frame = CGRectMake(8,10, 85, 85)
let path = UIBezierPath(rect: CGRectMake(8, 10, 85, 85))
textView?.textContainer.exclusionPaths = [path]
textView?.addSubview(capturedImageView!)
facebookButton?.tag = 1
facebookButton!.adjustsImageWhenHighlighted = false
facebookButton?.addTarget(self, action: "tapSocial:", forControlEvents: UIControlEvents.TouchUpInside)
facebookButton?.tintColor = UIColor.whiteColor()
facebookButton?.backgroundColor = UIColor(hexString: "#395798")
facebookButton?.contentMode = UIViewContentMode.Center
facebookButton?.setTitle("", forState: UIControlState.Normal)
let fBorder = CALayer()
let width = CGFloat(1.0)
fBorder.borderColor = UIColor.whiteColor().colorWithAlphaComponent(0.05).CGColor
fBorder.frame = CGRect(x: 0, y: facebookButton!.frame.size.height - width, width: facebookButton!.frame.size.width, height: facebookButton!.frame.size.height)
fBorder.borderWidth = width
facebookButton!.layer.addSublayer(fBorder)
facebookButton!.layer.masksToBounds = true
twitterButton?.tag = 2
twitterButton!.adjustsImageWhenHighlighted = false
twitterButton?.addTarget(self, action: "tapSocial:", forControlEvents: UIControlEvents.TouchUpInside)
twitterButton?.contentMode = UIViewContentMode.Center
twitterButton?.tintColor = UIColor.whiteColor()
twitterButton?.setTitle("", forState: UIControlState.Normal)
let tBorder = CALayer()
tBorder.borderColor = UIColor.whiteColor().colorWithAlphaComponent(0.05).CGColor
tBorder.frame = CGRect(x: 0, y: twitterButton!.frame.size.height - width, width: twitterButton!.frame.size.width, height: twitterButton!.frame.size.height)
tBorder.borderWidth = width
twitterButton!.layer.addSublayer(tBorder)
twitterButton!.layer.masksToBounds = true
let tRightBorder = CALayer()
tRightBorder.borderColor = UIColor.whiteColor().colorWithAlphaComponent(0.05).CGColor
tRightBorder.frame = CGRect(x: 0, y: 0, width: width, height: twitterButton!.frame.size.height)
tRightBorder.borderWidth = width
twitterButton!.layer.addSublayer(tRightBorder)
instagramButton?.tag = 3
instagramButton!.adjustsImageWhenHighlighted = false
instagramButton?.addTarget(self, action: "tapSocial:", forControlEvents: UIControlEvents.TouchUpInside)
instagramButton?.contentMode = UIViewContentMode.Center
instagramButton?.tintColor = UIColor.whiteColor()
instagramButton?.setTitle("", forState: UIControlState.Normal)
let iBorder = CALayer()
iBorder.borderColor = UIColor.whiteColor().colorWithAlphaComponent(0.05).CGColor
iBorder.frame = CGRect(x: 0, y: instagramButton!.frame.size.height - width, width: instagramButton!.frame.size.width, height: instagramButton!.frame.size.height)
iBorder.borderWidth = width
instagramButton!.layer.addSublayer(iBorder)
instagramButton!.layer.masksToBounds = true
let iLeftBorder = CALayer()
iLeftBorder.borderColor = UIColor.whiteColor().colorWithAlphaComponent(0.05).CGColor
iLeftBorder.frame = CGRect(x: 0, y: 0, width: width, height: instagramButton!.frame.size.height)
iLeftBorder.borderWidth = width
instagramButton!.layer.addSublayer(iLeftBorder)
}
This came as a surprise for me but apparently there is a performance issue with textView's property "selectable" when set to true by default (checked on Storyboard).
Try going to your Storyboard, select each textView and uncheck the box "selectable". If you need the textView to be selectable, then just set selectable to true programatically on your viewDidLoad.

Resources