Reduce the code using a method - ios

Hello there I'm doing the Udacity nanodegree, I'm working with textFields, but I need to reduce the code using a method that takes UITextField as parameter.
I actually I don't know what the method could be, and I don't have any idea how to reduce the code.
I will let you the code that and hope you can help me
let memeTextAttributes = [
NSStrokeColorAttributeName : UIColor.blackColor(), NSForegroundColorAttributeName : UIColor.blueColor(), NSFontAttributeName : UIFont(name: "HelveticaNeue-CondensedBlack", size: 40)!, NSStrokeWidthAttributeName : -1.0]
override func viewDidLoad() {
super.viewDidLoad()
topText.defaultTextAttributes = memeTextAttributes
bottomText.defaultTextAttributes = memeTextAttributes
topText.textAlignment = NSTextAlignment.Center
bottomText.textAlignment = NSTextAlignment.Center
shareButton.enabled = false

You can use something like this:
func configTextField(defaultText: String, textField: UITextField)
{
textField.text = defaultText
textField.defaultTextAttributes = memeTextAttributes
textField.autocapitalizationType = .AllCharacters
textField.textAlignment = .Center
textField.delegate = self
}
Since it is a meme you can automatically capitalize the whole text.
Then call the above function in viewDidLoad.
For example, the bottom textField will be called in viewDidLoad by:
configTextField("BOTTOM", textField: bottomTextField)

Related

how to remove place holder text from textfield using Google Material MDCOutlinedTextField in swift?

here is the code I wrote but when the user is in text field but there is no text still place holder appears in textfield in also showing in the floating label I just want to remove when I am inside this textfield
func setupGoogleMaterialTextFields(textFields: [MDCOutlinedTextField]) {
let containerShceme = MDCContainerScheme()
let colorScheme = MDCSemanticColorScheme()
colorScheme.primaryColor = UIColor.white
colorScheme.onSurfaceColor = UIColor.white
containerShceme.colorScheme = colorScheme
for textField in textFields {
textField.label.text = textField.placeholder
textField.font = UIFont.myMediumSystemFont(ofSize: 18)
textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder ?? "",
attributes: [NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.myMediumSystemFont(ofSize: 16)])
textField.containerRadius = 8
textField.sizeToFit()
textField.applyTheme(withScheme: containerShceme)
}
}
I have assigned the delegate to the textField like this.
func setupGoogleMaterialTextFields(textFields: [MDCOutlinedTextField]) {
let containerShceme = MDCContainerScheme()
let colorScheme = MDCSemanticColorScheme()
colorScheme.primaryColor = UIColor.white
colorScheme.onSurfaceColor = UIColor.white
containerShceme.colorScheme = colorScheme
for textField in textFields {
textField.label.text = textField.placeholder
textField.font = UIFont.myMediumSystemFont(ofSize: 18)
textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder ?? "",
attributes: [NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.myMediumSystemFont(ofSize: 16)])
textField.containerRadius = 8
textField.sizeToFit()
textField.applyTheme(withScheme: containerShceme)
textField.delegate = self
}
}
After Assigning the Delegate do this.
extension youClassName: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.text?.isEmpty ?? false {
textField.placeholder = nil
}
}
}

Subclassing UIViewController With NavigationBar Title

I'm trying to subclass a UIViewController with a label (UILabel) set to the title of the navigation bar. Instead of setting a name to self.title, I want to use an attributed string to set the title.
class BasicViewController: UIViewController {
var titleString = ""
func setup() {
//self.title = titleString
let navBar = navigationController!.navigationBar
navBar.barTintColor = UIColor.redColor()
let atext = NSMutableAttributedString(string: titleString)
atext.addAttribute(NSForegroundColorAttributeName, value: UIColor.whiteColor(), range: NSMakeRange(0, atext.length))
atext.addAttribute(NSStrokeColorAttributeName, value: UIColor.yellowColor(), range: NSMakeRange(0, atext.length))
atext.addAttribute(NSStrokeWidthAttributeName, value: NSNumber.init(float: -1.0), range: NSMakeRange(0, atext.length))
let titleLabel:UILabel = UILabel.init(frame: CGRectMake(50, 3, 220, 44))
titleLabel.attributedText = atext
titleLabel.textAlignment = NSTextAlignment.Center
titleLabel.font = UIFont(name: "Helvetica", size: 24.0)
}
}
class HomeViewController: BasicViewController {
override func viewDidLoad() {
super.viewDidLoad()
titleString = "My App"
setup()
}
}
If I run this code, I get an empty title. What am I doing wrong? Thanks.
I don't see where you're setting self.navigationItem.titleView = titleLabel

How to access programatically created UI object from a calss member function

I created a text view programatically and I have an external function outside viewdidload within which I want to change the contents of that textview. How do I achieve that? Here's the code I'm working with
As things stand. I'm currently getting this error "Value of type 'UIView' has no member 'textView' " on the line
self.view.textView.text = "Yo Dawg!!"
class rootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let myTextView = UITextView(frame: CGRectMake(0,0,100,50))
myTextView.backgroundColor = UIColor.clearColor()
myTextView.textColor = UIColor.whiteColor()
myTextView.font = UIFont (name: "Helvetica Neue", size: 20)
myTextView.textAlignment = NSTextAlignment.Center
myTextView.text = "Hello World"
self.view.addSubview(timerView)
}//End view did load
func changeText(){//This function updates the text within the textview
self.view.textView.text = "Yo Dawg!!"
}//End change text function
}//End rootViewController
You could assign an unique tag to the textview and use it to get the reference.
override func viewDidLoad() {
super.viewDidLoad()
let myTextView = UITextView(frame: CGRectMake(0,0,100,50))
myTextView.backgroundColor = UIColor.clearColor()
myTextView.textColor = UIColor.whiteColor()
myTextView.font = UIFont (name: "Helvetica Neue", size: 20)
myTextView.textAlignment = NSTextAlignment.Center
myTextView.text = "Hello World"
myTextView.tag = 1
self.view.addSubview(timerView)
}
func changeText(){
if let myTextView = self.view.viewWithTag(1) as? UITextView {
myTextView.text = "Yo Dawg!!"
}
}
You need to keep a reference to your text view in an instance variable/property, not in a local variable:
class rootViewController: UIViewController {
var myTextView:UITextView!
override func viewDidLoad() {
super.viewDidLoad()
self.myTextView = UITextView(frame: CGRectMake(0,0,100,50))
self.myTextView.backgroundColor = UIColor.clearColor()
self.myTextView.textColor = UIColor.whiteColor()
self.myTextView.font = UIFont (name: "Helvetica Neue", size: 20)
self.myTextView.textAlignment = NSTextAlignment.Center
self.myTextView.text = "Hello World"
self.view.addSubview(timerView)
}//End view did load
func changeText(){//This function updates the text within the textview
self.myTextView.text = "Yo Dawg!!"
}//End change text function
}

Swift - UIButton with two lines of text

I was wondering if it is possible to create a UIButton with two lines of text. I need each line to have a different font size. The first line will be 17 point and the second will be 11 point. I've tried messing with putting two labels inside of a UIButton, but I can't get them to stay inside the bounds of the button.
I'm attempting to do all of this in the ui builder, and not programmatically.
Thanks
There are two questions.
I was wondering if it is possible to create a UIButton with two lines
of text
This is possible through using the storyboard or programmatically.
Storyboard:
Change the 'Line Break Mode' to Character Wrap or Word Wrap and use Alt/Option + Enter key to enter a new line in the UIButton's Title field.
Programmatically:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}
I need each line to have a different font size
1
The worst case is, you can use a custom UIButton class and add two labels within it.
The better way is, make use of NSMutableAttributedString. Note that,this can be achieved through only programmatically.
Swift 5:
#IBOutlet weak var btnTwoLine: UIButton?
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
//applying the line break mode
textResponseButton?.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
let buttonText: NSString = "hello\nthere"
//getting the range to separate the button title strings
let newlineRange: NSRange = buttonText.range(of: "\n")
//getting both substrings
var substring1 = ""
var substring2 = ""
if(newlineRange.location != NSNotFound) {
substring1 = buttonText.substring(to: newlineRange.location)
substring2 = buttonText.substring(from: newlineRange.location)
}
//assigning diffrent fonts to both substrings
let font1: UIFont = UIFont(name: "Arial", size: 17.0)!
let attributes1 = [NSMutableAttributedString.Key.font: font1]
let attrString1 = NSMutableAttributedString(string: substring1, attributes: attributes1)
let font2: UIFont = UIFont(name: "Arial", size: 11.0)!
let attributes2 = [NSMutableAttributedString.Key.font: font2]
let attrString2 = NSMutableAttributedString(string: substring2, attributes: attributes2)
//appending both attributed strings
attrString1.append(attrString2)
//assigning the resultant attributed strings to the button
textResponseButton?.setAttributedTitle(attrString1, for: [])
}
Older Swift
#IBOutlet weak var btnTwoLine: UIButton?
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
//applying the line break mode
btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
var buttonText: NSString = "hello\nthere"
//getting the range to separate the button title strings
var newlineRange: NSRange = buttonText.rangeOfString("\n")
//getting both substrings
var substring1: NSString = ""
var substring2: NSString = ""
if(newlineRange.location != NSNotFound) {
substring1 = buttonText.substringToIndex(newlineRange.location)
substring2 = buttonText.substringFromIndex(newlineRange.location)
}
//assigning diffrent fonts to both substrings
let font:UIFont? = UIFont(name: "Arial", size: 17.0)
let attrString = NSMutableAttributedString(
string: substring1 as String,
attributes: NSDictionary(
object: font!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
let font1:UIFont? = UIFont(name: "Arial", size: 11.0)
let attrString1 = NSMutableAttributedString(
string: substring2 as String,
attributes: NSDictionary(
object: font1!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
//appending both attributed strings
attrString.appendAttributedString(attrString1)
//assigning the resultant attributed strings to the button
btnTwoLine?.setAttributedTitle(attrString, forState: UIControlState.Normal)
}
Output
I was looking for nearly the same topic, except that I don't need two different font sizes. In case someone is looking for a simple solution:
let button = UIButton()
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = .byWordWrapping
button.setTitle("Foo\nBar", for: .normal)
button.titleLabel?.textAlignment = .center
button.sizeToFit()
button.addTarget(self, action: #selector(rightBarButtonTapped), for: .allEvents)
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
I have notice an issue in most of the solutions which is while making line break mode to "Character Wrap" the second line will be left aligned to the first line
To make all the lines centered.
just change the title From Plain to Attributed and then you can make each line centered
change line break to character wrap , select your button and in attribute inspector go to line break and change it to character wrap
SWIFT 3 Syntax
let str = NSMutableAttributedString(string: "First line\nSecond Line")
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 17), range: NSMakeRange(0, 10))
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(11, 11))
button.setAttributedTitle(str, for: .normal)
I have fixed this and my solution it was only in the Storyboard.
Changes:
It added in Identity Inspector -> User Defined Runtime Attributes (these KeyPaths):
numberOfLines = 2
titleLabel.textAlignment = 1
User Defined Runtime Attributes
I added this in attributes inspector:
line break = word wrap
Word wrap
You need to do some of this in code. you can't set 2 different fonts in IB. In addition to changing the line break mode to character wrap, you need something like this to set the title,
override func viewDidLoad() {
super.viewDidLoad()
var str = NSMutableAttributedString(string: "First line\nSecond Line")
str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(17), range: NSMakeRange(0, 10))
str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(12), range: NSMakeRange(11, 11))
button.setAttributedTitle(str, forState: .Normal)
}
New with Xcode 13 (iOS 15)
Starting with Xcode 13, the button's title and subtitle may have their attributes set separately.
Using Storyboard:
In the Attribute Inspector for the button, select "Attributed" by Title. Then change font size of the title and the subtitle.
Or Programmatically:
// Create Title
let titleSettings = AttributeContainer.font( UIFont(name: "HelveticaNeue-Italic", size: 17)! )
yourButton.configuration?.attributedTitle = AttributedString("Button's Title", attributes: titleSettings)
// Create Subtitle
let subtitleSettings = AttributeContainer.font( UIFont(name: "HelveticaNeue-Italic", size: 11)! )
yourButton.configuration?.attributedSubtitle = AttributedString("Button's Subtitle", attributes: subtitleSettings)
One way to do it is with labels, I guess. I did this, and it seems to work ok. I could create this as a UIButton and then expose the labels, I guess. I don't know if this makes any sense.
let firstLabel = UILabel()
firstLabel.backgroundColor = UIColor.lightGrayColor()
firstLabel.text = "Hi"
firstLabel.textColor = UIColor.blueColor()
firstLabel.textAlignment = NSTextAlignment.Center
firstLabel.frame = CGRectMake(0, testButton.frame.height * 0.25, testButton.frame.width, testButton.frame.height * 0.2)
testButton.addSubview(firstLabel)
let secondLabel = UILabel()
secondLabel.backgroundColor = UIColor.lightGrayColor()
secondLabel.textColor = UIColor.blueColor()
secondLabel.font = UIFont(name: "Arial", size: 12)
secondLabel.text = "There"
secondLabel.textAlignment = NSTextAlignment.Center
secondLabel.frame = CGRectMake(0, testButton.frame.height * 0.5, testButton.frame.width, testButton.frame.height * 0.2)
testButton.addSubview(secondLabel)
The suggested solutions unfortunately did not work out for me when I wanted to have a mutliline button inside a CollectionView. Then a colleague showed me a workaround which I wanted to share in case someone has the same problem - hope this helps! Create a class which inherits from UIControl and extend it with a label, which will then behave similar like a button.
class MultilineButton: UIControl {
let label: UILabel = {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.numberOfLines = 0
$0.textAlignment = .center
return $0
}(UILabel())
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(label)
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
])
}
override var isHighlighted: Bool {
didSet {
backgroundColor = backgroundColor?.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
label.textColor = label.textColor.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
my way:
func setButtonTitle(title: String, subtitle: String, button: UIButton){
//applying the line break mode
button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
let title = NSMutableAttributedString(string: title, attributes: Attributes.biggestLabel)
let subtitle = NSMutableAttributedString(string: subtitle, attributes: Attributes.label)
let char = NSMutableAttributedString(string: "\n", attributes: Attributes.biggestLabel)
title.append(char)
title.append(subtitle)
button.setAttributedTitle(title, for: .normal)
}

Center align placeholder in textfield

I know this question been asked many times but as drawinrect deprecated and I need this in ios 8.As I have a textfield and I need the placeholder in center align and rest of the test left align.Please help me out.
You can center the placeholder by using an attributedPlaceholder with a paragraph style whose alignment is set to .center:
let centeredParagraphStyle = NSMutableParagraphStyle()
centeredParagraphStyle.alignment = .center
textField.attributedPlaceholder = NSAttributedString(
string: "Placeholder",
attributes: [.paragraphStyle: centeredParagraphStyle]
)
Create and connect IBOutlet to your textField. In YourViewController.m
#interface YourViewController () <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txt;
In your viewDidLoad
self.txt.delegate=self;
self.txt.textAlignment=NSTextAlignmentCenter;
Write this delegate method..this method calls everytime when text in text field changes.
- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {
NSRange textFieldRange = NSMakeRange(0, [self.txt.text length]);
// Check If textField is empty. If empty align your text field to center, so that placeholder text will show center aligned
if (NSEqualRanges(range, textFieldRange) && [string length] == 0) {
self.txt.textAlignment=NSTextAlignmentCenter;
}
else //else align textfield to left.
{
self.txt.textAlignment=NSTextAlignmentLeft;
}
return YES;
}
The answer by #Clay Ellis is correct, here it is for Objective-C:
UITextField* field = [[UITextField alloc] initWithFrame: fieldRect];
NSTextAlignment alignment = NSTextAlignmentCenter;
NSMutableParagraphStyle* alignmentSetting = [[NSMutableParagraphStyle alloc] init];
alignmentSetting.alignment = alignment;
NSDictionary *attributes = #{NSParagraphStyleAttributeName : alignmentSetting};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:placeholder attributes: attributes];
field.attributedPlaceholder = str;
The answer by #Clay Ellis in Swift 5
let centeredParagraphStyle = NSMutableParagraphStyle()
centeredParagraphStyle.alignment = .center
let attributedPlaceholder = NSAttributedString(string: "Placeholder", attributes: [NSAttributedString.Key.paragraphStyle: centeredParagraphStyle])
textField.attributedPlaceholder = attributedPlaceholder
based on Clay Ellis answer
Details
Xcode Version 10.2.1 (10E1001), Swift 5
Solution 1
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
textField.attributedText = NSAttributedString(string: placeholder, attributes: [.paragraphStyle: paragraphStyle])
Solution 2
import Foundation
extension String {
func toAttributed(alignment: NSTextAlignment) -> NSAttributedString {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
return toAttributed(attributes: [.paragraphStyle: paragraphStyle])
}
func toAttributed(attributes: [NSAttributedString.Key : Any]? = nil) -> NSAttributedString {
return NSAttributedString(string: self, attributes: attributes)
}
}
Usage of the solution 2
// Way 1
textField.attributedPlaceholder = text.attributedString(alignment: .center)
// Way 2
textField.attributedPlaceholder = "title".attributedString(alignment: .center)
Full sample
Do not forget to add the solution code here
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textField = UITextField()
textField.borderStyle = .roundedRect
view.addSubview(textField)
//textField.attributedPlaceholder = getAttributedString1()
textField.attributedPlaceholder = getAttributedString2()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 24).isActive = true
textField.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 16).isActive = true
view.safeAreaLayoutGuide.rightAnchor.constraint(equalTo: textField.rightAnchor, constant: 16).isActive = true
}
private func getAttributedString1() -> NSAttributedString {
return "placeholder".toAttributed(alignment: .center)
}
private func getAttributedString2() -> NSAttributedString {
var attributes = [NSAttributedString.Key: Any]()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
attributes[.paragraphStyle] = paragraphStyle
attributes[.font] = UIFont.systemFont(ofSize: 12, weight: .bold)
attributes[.foregroundColor] = UIColor.black.withAlphaComponent(0.5)
attributes[.underlineStyle] = NSUnderlineStyle.single.rawValue
attributes[.underlineColor] = UIColor.red
return "placeholder".toAttributed(attributes: attributes)
}
}
Results

Resources