How to print multiple textfield in center of view programmatically? - iphone

I am trying to print multiple textField in middle of the view but I can't. I wanna clickable textfield.textfield should be middle of the view and font size will be manage as textfield size.
This is my code:
for i in 0..<characters.count
{
let textField : UITextField = UITextField(frame : CGRect(x:(charWidth/13) * CGFloat(i) + CenterX, y:0, width:charWidth/14, height:charWidth/12))
textField.font = UIFont(name: "Noteworthy", size: 50)
textField.text = "\(characters[i])".lowercased()
textField.textAlignment = .center
textField.resizeText()
textField.adjustsFontSizeToFitWidth = true
textField.minimumFontSize = 1.0
textField.delegate = self
textField.autocapitalizationType = .none
//textView.font = UIFont
}

Try simply use different method for a textField and firstly you take textField not a textView. All textFields have a its own outlets.
How do I check when a UITextField changes?
https://developer.apple.com/reference/uikit/uitextfielddelegate
Here is the code for Swift 3 clickable textField:
myTextField.addTarget(self, action: #selector(myTargetFunction), for: .touchDown)
This is the function:
func myTargetFunction() {
print("It works!")
}

Related

UILabel and UIButton sizeToFit height are different in Swift

I am trying to align my UIButton and UILabel, however when I use size to fit for each of them the frame is of a different height. I want my UIButton frame height to be the same height as my UILabel. Both views added as subview on my main view, in my viewdidload. This is what I get
//create account button
let createAccount: UIButton = {
let create = UIButton()
create.translatesAutoresizingMaskIntoConstraints = false
create.setTitleColor(.orange, for: .normal)
create.setTitle("Create", for: .normal)
create.titleLabel?.font = UIFont.systemFont(ofSize: 18)
create.addTarget(self, action: #selector(forgot(_ :)), for: .touchUpInside)
create.sizeToFit()
create.backgroundColor = .red
return create
}()
let phraseOne: UILabel = {
let labelOne = UILabel()
labelOne.translatesAutoresizingMaskIntoConstraints = false
labelOne.text = "Dont have an account?"
labelOne.font = UIFont(name: labelOne.font.fontName, size: 18)
labelOne.textAlignment = .right
labelOne.sizeToFit()
labelOne.textColor = .white
labelOne.backgroundColor = .red
return labelOne
}()
override func viewDidLoad() {
super.viewDidLoad()
//Add subview phraseOne Forgot your password?
view.addSubview(phraseOne)
setupPhraseOne() //add constraints
view.addSubview(createAccount)
setupCreate() // add constraints
}

Search bar with corner radius in swift

I want to create a view like the above image.it has a search bar with corner radius.but when i am trying to create, i am unable to make the search bar with corner radius.also i am unable to make the text field of the search bar with corner radius. i have writtenall my code in viewDidAppear method. It is ok or i have to write it in viewWillLayourSubview. so that i will be able to make the exact
same search bar like this image. also i want the seach icon to be placed slightly right.
My code is:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
for subView in searchBar.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
var bounds: CGRect
var placeHolder = NSMutableAttributedString()
let Name = "Search"
placeHolder = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica", size: 15.0)!])
placeHolder.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.gray, range:NSRange(location:0,length:Name.count))
textField.attributedPlaceholder = placeHolder
if let leftView = textField.leftView as? UIImageView {
leftView.image = leftView.image?.withRenderingMode(.alwaysTemplate)
leftView.frame.size.width = 15.0
leftView.frame.size.height = 15.0
leftView.tintColor = UIColor.gray
}
textField.layer.cornerRadius = 50.0
bounds = textField.frame
bounds.size.width = searchBar.frame.width
bounds.size.height = searchBar.frame.height
textField.bounds = bounds
textField.borderStyle = UITextField.BorderStyle.roundedRect
searchBar.backgroundImage = UIImage()
textField.backgroundColor = UIColor.lightGray.withAlphaComponent(0.2)
searchBar.searchTextPositionAdjustment = UIOffset(horizontal: 5, vertical: 0)
}
}
}
}*
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
for subView in searchBar.subviews {
if !subView.subviews.contains(where: { $0 as? UITextField != nil }) { continue }
guard let textField = subView.subviews.first(where: { $0 as? UITextField != nil }) as? UITextField else { return }
let placeholder = NSMutableAttributedString(
string: "Search",
attributes: [.font: UIFont(name: "Helvetica", size: 15.0)!,
.foregroundColor: UIColor.gray
])
textField.attributedPlaceholder = placeholder
textField.borderStyle = UITextField.BorderStyle.roundedRect
textField.layer.cornerRadius = textField.frame.size.height / 2
textField.layer.masksToBounds = true
textField.textColor = .white
textField.backgroundColor = .lightGray
}
searchBar.barTintColor = .white
searchBar.backgroundColor = .white
searchBar.searchTextPositionAdjustment = UIOffset(horizontal: 5, vertical: 0)
}
Doesn't look exactly like in the image that you linked, but actually fits better into the Apple design and works better than the code that you wrote.
For anything more sophisticated, I would advise to create a custom UISearchBar subclass.
Be aware of Apple's Human Interface Guidelines, so anything too crazy / different from default might not be accepted in the AppStore.

Label does not adjust Font Size to fit width

This is how my app looks although I entered this code inside my ViewController class:
#IBOutlet var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label.text = "Hello World"
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
label.minimumScaleFactor = 0.1
}
Your text data is not more than label width that's why label text font is same as already set.
IF your text data is more then label width then it will adjust font according to the width.
Please check with label text: "This is the demo to test label text is adjustable or not. You need to test it with this demo data"
Your label font will adjust according to the width.
The font will adjust if the given text is greater than the width of the label.
Try this in playground:
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
label.backgroundColor = UIColor.lightGray
label.text = "Hello World! How are you doing today? "
label.textColor = .black
view.addSubview(label)
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
The result is the following:
I was able to get my UILabel font to dynamically adjust to the necessary size to fit into its parent by following this simple gitconnected article (See link to get all required code!!). I only needed to make two adjustments which were adding the lines label.baselineAdjustment = .alignCenters and label.numberOfLines = 1 so that my label creation now looked like this...
let dynamicFontLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 40)
label.textAlignment = .center
label.numberOfLines = 1;
label.textColor = .black
label.adjustsFontSizeToFitWidth = true
label.baselineAdjustment = .alignCenters
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
The label.baselineAdjustment = .alignCenters property ensured that if my font size was too large and needed to be downsized, my text would still remain centered vertically in the UILabel. I also only wanted my text to only span one line so if you want more than that you can just remove the label.numberOfLines = 1 property.

Changing the color of the icons in a UItextField inside a UISearchBar

I'm trying to customise the appearance of the search bar in my search controller.
Setting the background and text colors works fine but I just didn't find a way to change the color of the icons in the text field, specifically the magnifying glass and the x button.
I've found this Objective-C code which should do what I want but I'm struggling to translate it to Swift:
(EDIT: Skip to the first answer for the working Swift 3 solution.)
UITextField *searchBarTextField = [self.searchDisplayController.searchBar valueForKey:#"_searchField"];
// Magnifying glass icon.
UIImageView *leftImageView = (UIImageView *)searchBarTextField.leftView;
leftImageView.image = [LeftImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
leftImageView.tintColor = [UIColor whiteColor];
// Clear button
UIButton *clearButton = [searchBarTextField valueForKey:#"_clearButton"];
[clearButton setImage:[clearButton.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
clearButton.tintColor = [UIColor whiteColor];
My attempt to translate to Swift:
let textField = searchController.searchBar.valueForKey("searchField") as! UITextField
// These two work fine.
textField.backgroundColor = UIColor.blackColor()
textField.textColor = UIColor.blackColor()
var glassIcon = textField.leftView
// This would work.
//glassIcon.hidden = true
// This does not have any effect.
//glassIcon?.tintColor = UIColor.whiteColor()
// My attempt to translate, but it gives an error.
glassIcon.image? = UIImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
var clearButton = textField.valueForKey("clearButton")!
clearButton.setImage(clearButton.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
// This gives the error: "Cannot assign to property: 'clearButton' is immutable
clearButton.tintColor = UIColor.whiteColor()
// Sorry for the weird formatting, it glitches here in the editor.
The leftView does not seem to have an image property. How can I access that property as the Objective-C code does?
Also, if there is a better to achieve what I want please let me know.
Here is the solution:
// Text field in search bar.
let textField = searchController.searchBar.value(forKey: "searchField") as! UITextField
let glassIconView = textField.leftView as! UIImageView
glassIconView.image = glassIconView.image?.withRenderingMode(.alwaysTemplate)
glassIconView.tintColor = UIColor.white
let clearButton = textField.valueForKey("clearButton") as! UIButton
clearButton.setImage(clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate), for: .normal)
clearButton.tintColor = UIColor.white
Here is the solution:
extension UITextField{
func setLeftIcon(_ icon: UIImage) {
let padding = 8
let size = 20
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size+padding, height: size) )
let iconView = UIImageView(frame: CGRect(x: padding, y: 0, width: size, height: size))
iconView.image = icon.withRenderingMode(.alwaysTemplate)
iconView.tintColor = UIColor.white
outerView.addSubview(iconView)
leftView = outerView
leftViewMode = .always
}
}

How to resize Title in a navigation bar dynamically

I have some views that show up in a navigation controller. Two of these views have a longer title for the navigation bar.
The problem is that when the title is too long to fit, some characters are truncated and "..." is added.
Is there any way I can tell the Navigation bar to re-size the title text automatically to fit?
Used the below code in ViewDidload .
Objective C
self.title = #"Your TiTle Text";
UILabel* tlabel=[[UILabel alloc] initWithFrame:CGRectMake(0,0, 200, 40)];
tlabel.text=self.navigationItem.title;
tlabel.textColor=[UIColor whiteColor];
tlabel.font = [UIFont fontWithName:#"Helvetica-Bold" size: 30.0];
tlabel.backgroundColor =[UIColor clearColor];
tlabel.adjustsFontSizeToFitWidth=YES;
tlabel.textAlignment = NSTextAlignmentCenter;
self.navigationItem.titleView=tlabel;
Swift Version
self.title = "Your Title Text"
let tlabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
tlabel.text = self.title
tlabel.textColor = UIColor.white
tlabel.font = UIFont.systemFont(ofSize: 30, weight: .bold)
tlabel.backgroundColor = UIColor.clear
tlabel.adjustsFontSizeToFitWidth = true
tlabel.textAlignment = .center
self.navigationItem.titleView = tlabel
Hope it works for you.Thanks
Swift version of Accepted Answer + putting the label text on center :
Swift 2.3:
self.title = "Your TiTle Text"
let tlabel = UILabel(frame: CGRectMake(0, 0, 200, 40))
tlabel.text = self.title
tlabel.textColor = UIColor.whiteColor()
tlabel.font = UIFont.boldSystemFontOfSize(17) //UIFont(name: "Helvetica", size: 17.0)
tlabel.backgroundColor = UIColor.clearColor()
tlabel.adjustsFontSizeToFitWidth = true
tlabel.textAlignment = .Center
self.navigationItem.titleView = tlabel
And Swift 3 :
self.title = "Your TiTle Text"
let frame = CGRect(x: 0, y: 0, width: 200, height: 40)
let tlabel = UILabel(frame: frame)
tlabel.text = self.title
tlabel.textColor = UIColor.white
tlabel.font = UIFont.boldSystemFont(ofSize: 17) //UIFont(name: "Helvetica", size: 17.0)
tlabel.backgroundColor = UIColor.clear
tlabel.adjustsFontSizeToFitWidth = true
tlabel.textAlignment = .center
self.navigationItem.titleView = tlabel
This works for me
Objective C
[UILabel appearanceWhenContainedInInstancesOfClasses:#[[UINavigationBar class]]].adjustsFontSizeToFitWidth = YES;
Swift Version
UILabel.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).adjustsFontSizeToFitWidth = true
In case you have a view added into titleView, and you want to resize the view, you can use this code (Swift 3):
self.translatesAutoresizingMaskIntoConstraints = false
self.layoutIfNeeded()
self.sizeToFit()
self.translatesAutoresizingMaskIntoConstraints = true
None of the above solutions seam to work reliably for me.
However I found a solution by using different elements of the provides answers, its in Swift 2 and is really elegant as it does not require any custom code each time you change the label, it just uses property observers on the title.
Note that in my case, I had a back button on the left side of the navigation bar, which putted the text out of the center of the screen, to fix this I am using attributed text and the tailIndent. All comments/info in the code below :
class VCHowToTopic : UIViewController {
//add handlers so that any manipulation of the title is caught and transferred to the custom drawn UILabel
override var title : String? {
set {
super.title = newValue
configureTitleView()
}
get {
return super.title
}
}
//MARK: - lifecycle
func configureTitleView() {
//some large number that makes the navigationbar schrink down our view when added
let someVeryLargeNumber = CGFloat(4096)
//create our label
let titleLabel = UILabel(frame: CGRect(x: 0, y: 0, width: someVeryLargeNumber, height: someVeryLargeNumber))
//0 means unlimited number of lines
titleLabel.numberOfLines = 0
//define style of the text (we will be using attributed text)
let style = NSMutableParagraphStyle()
style.alignment = .Center
//top compensate for the backbutton which moves the centered text to the right side of the screen
//we introduce a negative tail indent, the number of 56 has been experimentally defined and might
//depend on the size of your custom back button (if you have one), mine is 22x22 px
style.tailIndent = -56
//create attributed text also with the right color
let attrText = NSAttributedString(string: title!, attributes: [NSParagraphStyleAttributeName : style,
NSForegroundColorAttributeName : UIColor.whiteColor()])
//configure the label to use the attributed text
titleLabel.attributedText = attrText
//add it as the titleview
navigationItem.titleView = titleLabel
}
}
You can create a UILabel as UINavigationItem's titleView and set it's adjustsFontSizeToFitWidth to true.
class MyViewController: UIViewController {
override var title: String? {
didSet {
(self.navigationItem.titleView as? UILabel)?.text = self.title
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.titleView = UILabel().apply {
$0.font = .boldSystemFont(ofSize: 18)
$0.minimumScaleFactor = 0.5
$0.adjustsFontSizeToFitWidth = true
$0.text = self.title
}
}
}
Easy to use:
myViewController.title = "This is a long title, but don’t worry."
The apply closure in the above code is a trick, in order to make the programming experience better. There is also a with closure. Recommend to everyone.
protocol ScopeFunc {}
extension ScopeFunc {
#inline(__always) func apply(_ block: (Self) -> ()) -> Self {
block(self)
return self
}
#inline(__always) func with<R>(_ block: (Self) -> R) -> R {
return block(self)
}
}
extension NSObject: ScopeFunc {}
Swift 5 and iOS 13 / iOS 14
The answers from above don't work if you have a large title in Swift 5 and iOS 13 because they simply add another title to your navigation bar. Instead you could use the largeTitleTextAttributes property (available since iOS 11) to shrink your title when needed.
Assuming you have set your large title via storyboard or code already, you can use the following method:
private func configureNavigationTitle(_ title: String) {
let tempLabel = UILabel()
tempLabel.font = UIFont.systemFont(ofSize: 34, weight: .bold)
tempLabel.text = title
if tempLabel.intrinsicContentSize.width > UIScreen.main.bounds.width - 30 {
var currentTextSize: CGFloat = 34
for _ in 1 ... 34 {
currentTextSize -= 1
tempLabel.font = UIFont.systemFont(ofSize: currentTextSize, weight: .bold)
if tempLabel.intrinsicContentSize.width < UIScreen.main.bounds.width - 30 {
break
}
}
navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: currentTextSize, weight: .bold)]
}
self.title = title
}
So essentially we are ussing a helper label in order to get the width of our title and then we are going to shrink the font size until the title fits in our navigation bar.
Call it from viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad(
configureNavigationTitle("A very long title which fits perfectly fine")
}
you need to customize the navigation bar title view with uilabel and provide adjust font size..
[self.navigationItem setTitleView:<"Include any UI View subclass">];
Just calling sizeToFit() on my view after the change worked for me
Here's an example in Swift that also allows for multiple lines. Using PureLayout to simplify auto layout.
override func viewDidLoad() {
super.viewDidLoad()
configureTitleView()
}
func configureTitleView() {
let titleLabel = UILabel()
titleLabel.numberOfLines = 0
titleLabel.textAlignment = .Center
titleLabel.font = UIFont.boldSystemFontOfSize(17.0)
titleLabel.text = searchLoc.mapItem.name
navigationItem.titleView = titleLabel
titleLabel.autoPinEdgesToSuperviewMargins() // PureLayout method
titleLabel.adjustsFontSizeToFitWidth = true
}
And a usage example:
Swift 4 and iOS 13
Adding this so my future self can find it. Views added to titleView for some reason don't like to automatically resize themselves. So you have to do it manually.
Example
(navigationItem.titleView as? UILabel)?.text = "A longer string..." // label not resized and text is cut off
Solution
navigationItem.titleView?.translatesAutoresizingMaskIntoConstraints = false
navigationItem.titleView?.setNeedsLayout()
navigationItem.titleView?.layoutIfNeeded()
navigationItem.titleView?.translatesAutoresizingMaskIntoConstraints = true
Thanks to #Paolo Musolino for leading me here.