padding setting for password field - ios

I am using Swift 3. I have two txtFields, one of them for email, the other one for password. I use the following code to give the email field a padding:
txtEmail.leftView = paddingView;
txtEmail.leftViewMode = .always
However, the app seems to run into an infinity loop when I apply the same to the password field:
txtPassword.leftView = paddingView;
txtPassword.leftViewMode = .always
What am I missing?

This UITextField extension will ease your implementation later on and should solve any problems related to using the same UIView on multiple textfields:
extension UITextField {
func pad(_ amount: Int) {
self.leftView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.height))
self.leftViewMode = UITextFieldViewMode.always
}
}
Then you can use it like this in viewDidLoad or anywhere lower in the view controller's call hierarchy
txtEmail.pad(15)
txtPassword.pad(15)

As your code display you are using same view object for both textfield at the same time and may be that's why your app is looping. you can not add same view object as a subview for two diffrent textfield at the same time. so create new view instance and set it as a padding for individual textfiled.
let paddingForEmail = UIView(frame: CGRectMake(0, 0, 15,txtEmail.frame.size.height))
//Adding the padding to the Email textField
txtEmail.leftView = paddingForFirst
txtEmail.leftViewMode = UITextFieldViewMode .Always
//Create new padding object of view for second textField
let paddingForPassword = UIView(frame: CGRectMake(0, 0, 15,txtPassword.frame.size.height))
//Add padding to the Password textField
txtPassword.leftView = paddingForPassword
txtPassword.leftViewMode = UITextFieldViewMode .Always
hope this will help you.

Related

Unable to show the Left view in UITextField

I am unable to show the left view in the UITextField. I know this is very easy thing and has been asked many times. I have found solutions to make a custom view and to show it as a left view.
I am trying to make a UILabel that shows the country code in the text field. I made the following function but it shows the empty space only.
func setCountryCode(textField: UITextField){
let viewPadding = UILabel(frame: CGRect(x: Int(textField.frame.origin.x), y: Int(textField.frame.origin.y), width: width , height: Int(textField.frame.size.height)))
viewPadding.textColor = CommonUtils.hexStringToUIColor(hex: AppColor.colorTextSecondary)
viewPadding.text = mCallingCode
viewPadding.font = viewPadding.font.withSize(12)
viewPadding.textAlignment = .center
textField.leftView = viewPadding
textField.leftViewMode = .whileEditing
}

How to add text field auto suggestions in a drop down list?

I have one Billing Address page in the app. I have to remember all text field data adds by the user and show them in a drop down list.
I have to create a table view on the bottom of the text fields. I am also using IQKeyboardManager for maintaining text fields when the keyboard appears.
So, when the keyboard appears, the table view is overlapping on the back of keyboard. How to resolve this issue?
I am also attaching the screenshot:
As i doing some search i found keyboardDistanceFromTextField property of IQKeyboardmanager class. You can set disctance of keyboard for the specific textField object using following code:
YourDropDowntextFiled.keyboardDistanceFromTextField = 250;
So make use of this line of code for your textfiled and you can easily show the drop-down list visible.
I have checked in Demo look like following. One i did not add keyboardDistanceFromTextField so it just appear after keyboard and other i apply propery so it will show big distance from the keyboard.
Look This. You can use RxSwift for compact coding
var autoCompleteTableView: UITableView = UITableView()
let containerView: UIView = UIView()
var placesArray = Observable.just([String]())
func createAutocompleteContainer() {
let screenSize: CGRect = UIScreen.mainScreen().bounds
let width : CGFloat = screenSize.width-138
let height : CGFloat = 200
containerView.frame = CGRect(x: 130, y: 62, width: width, height: height)
autoCompleteTableView.frame = CGRect(x: 0, y: 0, width: containerView.frame.size.width, height: containerView.frame.size.height)
containerView.backgroundColor = UIColor.whiteColor()
placesArray
.bindTo(autoCompleteTableView.rx_itemsWithCellIdentifier("cell", cellType: UITableViewCell.self)) { (row, element, cell) in
cell.textLabel?.text = "\(element)"
cell.textLabel?.textColor = UIColor(hex: "#b2b2b2")
cell.textLabel?.font = UIFont.systemFontOfSize(13)
}
.addDisposableTo(disposeBag)
autoCompleteTableView
.rx_modelSelected(String)
.subscribeNext { value in
self.textField = value
self.containerView.removeFromSuperview()
}
.addDisposableTo(disposeBag)
self.containerView.addSubview(autoCompleteTableView)
self.view.addSubview(containerView)
}

Swift CGPoint x and y overrides programatic constraints

I am trying to programatically create some text fields, and use programatic constraints to lay them out as creating them in the interface builder and using that to create constrains will not work as everything else is created programatically. So the problem is that to create a Text field, I have to use frame: CGRect(x y width height). But doing this overrides all the programatic constraints telling where to be placed based on other UI elements.
// Create username and password entry fields
let usernameTextField: UITextField
usernameTextField = UITextField(frame: CGRect(x: 0, y: 0, width: screenWidth - 40 - usernameLabel.bounds.width, height: 30)) // Without this line usernameTextField is uninitialised.
usernameTextField.textColor = UIColor.black()
usernameTextField.textAlignment = NSTextAlignment.left
usernameTextField.placeholder = "username"
self.view.addSubview(usernameTextField)
usernameTextField.translatesAutoresizingMaskIntoConstraints = true
let passwordTextField: UITextField
passwordTextField = UITextField(frame: CGRect(x: 0, y: 0, width: screenWidth - 40 - passwordLabel.bounds.width, height: 30))
passwordTextField.textColor = UIColor.black()
passwordTextField.textAlignment = NSTextAlignment.left
passwordTextField.placeholder = "password"
self.view.addSubview(passwordTextField)
passwordTextField.translatesAutoresizingMaskIntoConstraints = true
// Constraints for username and password entry fields
// Horizontal placement
usernameTextField.leadingAnchor.constraint(equalTo: usernameLabel.trailingAnchor).isActive = true
passwordTextField.leadingAnchor.constraint(equalTo: passwordLabel.trailingAnchor).isActive = true
// Verticle placement
usernameTextField.bottomAnchor.constraint(equalTo: usernameUnderline.topAnchor).isActive = true
passwordTextField.bottomAnchor.constraint(equalTo: passwordUnderline.topAnchor).isActive = true
//Width
usernameTextField.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
passwordTextField.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
So how can I programatically create these text fields and use constraints to place them?
Once you start adding constraints to a UIView, you have to go all in. Set translatesAutoresizingMaskIntoConstraints = false on your fields and then add constraints for the desired width, height, and placement.
In that case, you don't pass a frame to the UITextField constructor when you create it:
let usernameTextField = UITextField()
It looks like you are already accounting for usernameTextField's length by setting its leading and trailing anchors. So add a constraint for its height:
usernameTextField.heightAnchor.constraintEqualToConstant(30)
And repeat this for your passwordTextField.

Twitter-like UIScrollView with ViewControllers as pages

Video of the issue!
Example of what I mean by Twitter-like UIScrollView:
I basically have it working, but I have this small glaring issue and I don't know where it is coming from. I have checked all the constraints and values for my two view controllers, but something is off.
In short,
The code that creates the NavBar and then populates it with the two ViewControllers side by side:
override func viewDidLoad() {
super.viewDidLoad()
var navBar: UINavigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.bounds.width, 64))
navBar.barTintColor = UIColor.blackColor()
navBar.translucent = false
//Creating some shorthand for these values
var wBounds = self.view.bounds.width
var hBounds = self.view.bounds.height
// This houses all of the UIViews / content
scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.clearColor()
scrollView.frame = self.view.frame
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.delegate = self
scrollView.bounces = false
self.view.addSubview(scrollView)
self.scrollView.contentSize = CGSize(width: self.view.bounds.size.width * 2, height: hBounds)
//Putting a subview in the navigationbar to hold the titles and page dots
navbarView = UIView()
//Paging control is added to a subview in the uinavigationcontroller
pageControl = UIPageControl()
pageControl.frame = CGRect(x: 0, y: 35, width: 0, height: 0)
pageControl.pageIndicatorTintColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.3)
pageControl.currentPageIndicatorTintColor = UIColor.whiteColor()
pageControl.numberOfPages = 2
pageControl.currentPage = 0
self.navbarView.addSubview(pageControl)
//Titles for the nav controller (also added to a subview in the uinavigationcontroller)
//Setting size for the titles. FYI changing width will break the paging fades/movement
navTitleLabel1 = UILabel()
navTitleLabel1.frame = CGRect(x: 0, y: 8, width: wBounds, height: 20)
navTitleLabel1.textColor = UIColor.whiteColor()
navTitleLabel1.textAlignment = NSTextAlignment.Center
navTitleLabel1.text = "Title 1"
self.navbarView.addSubview(navTitleLabel1)
navTitleLabel2 = UILabel()
navTitleLabel2.alpha = 0.0
navTitleLabel2.frame = CGRect(x: 100, y: 8, width: wBounds, height: 20)
navTitleLabel2.textColor = UIColor.whiteColor()
navTitleLabel2.textAlignment = NSTextAlignment.Center
navTitleLabel2.text = "Title 2"
self.navbarView.addSubview(navTitleLabel2)
//Views for the scrolling view
//This is where the content of your views goes (or you can subclass these and add them to ScrollView)
feedViewController = storyboard?.instantiateViewControllerWithIdentifier("FeedController") as FeedViewController
view1 = feedViewController.view
addChildViewController(feedViewController)
feedViewController.didMoveToParentViewController(self)
view1.frame = CGRectMake(0, 0, wBounds, hBounds)
self.scrollView.addSubview(view1)
self.scrollView.bringSubviewToFront(view1)
//Notice the x position increases per number of views
secondViewController = storyboard?.instantiateViewControllerWithIdentifier("SecondController") as SecondViewController
view2 = secondViewController.view
addChildViewController(secondViewController)
secondViewController.didMoveToParentViewController(self)
view2.frame = CGRectMake(wBounds, 0, wBounds, hBounds)
self.scrollView.addSubview(view2)
self.scrollView.bringSubviewToFront(view2)
navBar.addSubview(navbarView)
self.view.addSubview(navBar)
}
I've looked at my storyboard and both ViewControllers seem identical in regards to their constraints.
I know this is an issue because both ViewControllers are populated by UITableViews. When I scroll through the SecondViewController, it works perfectly. When I scroll through the FeedViewController, there is a small white space at the top that I can't seem to get rid of and it shows that the text cuts off there. I've been stuck on this for a long time and if there is any other information needed, I'll gladly provide it.
Edit: Included video of the issue. If I could, I would bounty this question right now. I don't understand the cause
Update: After swapping both ViewController positions, I have noticed that the problem does not lie with either ViewController. The problem lies with page 1 being set lower. When swapped, the original SecondViewController also experienced the same behavior
So, I think everyone who implements this runs into this issue at some point. The issue isn't with the first ViewController. Simply adjust the constraint to be 44 from the top. The issue is with the second ViewController and it isn't so much an issue when you understand how they work. Technically, it is off to the side and hence its top constraint does not adhere to the Navigation Bar, so what you have is a constraint - 20. Which, depending on how you originally placed your constraints, can give you this seeming issue.
But basically, anyone and everyone will run into this issue when implementing this.
TL;DR: To make everything seamless, your second, third, fourth, fifth, etc. page View Controllers need a constraint + 20 of your first View Controller. With my set-up, I use a constraint of 44 for my first View Controller and hence 64 for the second

Position of rightView UITextField

Is there a way to adjust the position of a rightView on UITextField? I tried setting the frame on the view (set as rightView) but it didn't change anything.
I'd like to avoid making two views, one as the rightView and one as the rightView's subview where I change the subview's position, if possible.
The right overlay view is placed in the rectangle returned by the rightViewRectForBounds: method of the receiver.
So I suggest you subclass UITextField and override this method, something like this:
#interface CustomTextField: UITextField
#end
#implementation CustomTextField
// override rightViewRectForBounds method:
- (CGRect)rightViewRectForBounds:(CGRect)bounds{
CGRect rightBounds = CGRectMake(bounds.origin.x + 10, 0, 30, 44);
return rightBounds ;
}
#Puneet Sharma's answer was great but that would give the need to create a class that would subclass UITextField, what I did instead was create a UIView that would act as a padding.
This code works without the need to subclass
Here's my code, although it's written in Swift 3
// this is the view I want to see on the rightView
let checkImageView = UIImageView(image: UIImage(named: "check24.png"))
checkImageView.frame = CGRect(x: 0, y: 0, width: 24, height: 24)
checkImageView.curveEdges(12)
checkImageView.contentMode = .scaleAspectFit
// declare how much padding I want to have
let padding: CGFloat = 6
// create the view that would act as the padding
let rightView = UIView(frame: CGRect(
x: 0, y: 0, // keep this as 0, 0
width: checkImageView.frame.width + padding, // add the padding
height: checkImageView.frame.height))
rightView.addSubview(checkImageView)
// set the rightView UIView as the textField's rightView
self.textField.rightViewMode = .whileEditing
self.textField.rightView = rightView
What happened here is, that the rightView which is a UIView that has a transparent colored background which then gave the illusion that there is a padding whereas there is not.
Right Padding you can use as
let imageview = UIImageView(image: UIImage(named: "image name"))
imageview.contentMode = .center
let rightPadding: CGFloat = 14 //--- change right padding
imageview.frame = CGRect(x: 0, y: 0, width: imageview.frame.size.width + rightPadding , height:imageview.frame.size.height)
textField.rightViewMode = .always
textFieldd.rightView = imageview

Resources