Why is my left view in text field not working? - ios

I've added a left view to my text field using the code below:
usernameField.leftViewMode = UITextFieldViewMode.always
passwordField.leftViewMode = UITextFieldViewMode.always
let usernameImageView = UIImageView()
let usernameImage = UIImage(named: "user icon grey.png")
usernameImageView.image = usernameImage
usernameField.leftView = usernameImageView
let passwordImageView = UIImageView()
let passwordImage = UIImage(named: "lock icon grey.png")
passwordImageView.image = passwordImage
passwordField.leftView = passwordImageView
This didn't work, I then added a UIDesignable, a very neat process that I took from this question below on StackOverflow. This means that I can see the icons in the storyboard, as can be seen below. However, this doesn't show up.
Swift add icon/image in UITextField

The problem is with how you create the image view. You first create an empty image view which then has no size. You then assign the image to the image view but this does not automatically resize the image view.
There are two solutions.
Tell the image view to resize itself after assigning the image.
let usernameImageView = UIImageView()
let usernameImage = UIImage(named: "user icon grey.png")
usernameImageView.image = usernameImage
usernameImageView.sizeToFit()
Create the image view with the image. This is simpler approach.
let usernameImage = UIImage(named: "user icon grey.png")
let usernameImageView = UIImageView(image: usernameImage)

The problem is with your code. using this code now your left view in textField is working.
#IBOutlet weak var name: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
usernameField.leftViewMode = .always
let usernameImageView = UIImageView()
usernameImageView.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
let usernameImage = (your image name)
usernameImageView.image = usernameImage
usernameField.leftView = usernameImageView

Related

Modifying images of generated imageViews on button click

I am creating a quiz app and having trouble changing the image which is displayed of a specific imageview that is generated in a for loop.
The following code is responsible for generating the imageviews based on the amount of questions in that specific quiz. It is called in the viewDidLoad() method:
var imageView = UIImageView()
func addProgressImages(to view: UIView, count: Int){
let screenSize = UIScreen.main.bounds.size
for i in 0..<count {
let spacing: CGFloat = 2
let tag = i + 888
let width: CGFloat = screenSize.width/CGFloat(count)
let height: CGFloat = width
if let view = view.viewWithTag(tag){
view.removeFromSuperview()
}
let x = spacing + CGFloat(i) * width
imageView = UIImageView(frame: CGRect(x: x, y: 100, width: width - spacing, height: height))
imageView.image = UIImage(named: "question_progress_empty")
imageView.tag = tag
imageView.contentMode = .scaleAspectFit
view.addSubview(imageView)
//print("imageviews displaying")
}
}
I have made an attempt to change some of the images to another image when the user selects an answer to that question with an if statement:
func changeImage() {
if (optA != questionAns){
imageView.image = UIImage(named: "wrong_answer")
print("opta")
}else if(optB == questionAns){
imageView.image = UIImage(named: "wrong_answer")
print("optb")
}else if(optC == questionAns){
print("optc")
imageView.image = UIImage(named: "wrong_answer")
}else{
print("if statement not initialised")
}
}
https://imgur.com/a/zwJ4EVn - This is the output of the above code
Currently, only the last image will be changed when a user clicks a button.
I need help with modifying the imageview which is related to that specific question, e.g. if question 2 is answered, only that imageview will change while the rest remain unmodified.
Hopefully that explanation made any sense, any input would be appreciated,
Thanks.
See you are doing few things wrong.
you have taken UIImageView as instance variable as below, so after
creating all the images its holding the reference to the last
imageView.
var imageView = UIImageView()
Make the var imageView as local variable and in the func
changeImage() get the proper imageView using its tag value then
try to change its image.
If any doubt plz comment.
How to get the imageView back in changeImage() check below code.
let tag = 888 + (questionNumber - 1)
if let imageView = view.viewWithTag(tag) as? UIImageView {
// Change imageView's image here
}
You will probably want to create an array of image views:
var imageViews = [UIImageView]()
And add your UIImagesViews to that array in your loop:
for i in 0..<count {
var imageView = UIImageView()
// additional setup...
imageViews.append(imageView)
}
Then, you can later iterate over your array and change the images:
for imageView in imageViews {
imageView.image = UIImage(named: "wrong_answer")
// etc.
}

Add overlay to cover entire screen(including status bar)

I have an overlay (UIImageView) which should have a transparent background and alpha. How can I set the imageview such that it covers the entire screen? Currently, it covers the screen but not the UIStatusBar. I am adding the view in AppDelegate's main window as a subview.
The code:
let overlay1 = UIImageView(image: UIImage(named: "overlay-image"))
overlay1.contentMode = .scaleAspectFit
overlay1.backgroundColor = UIColor.black
overlay1.alpha = 0.87
overlay1.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
overlay1.isUserInteractionEnabled = true
overlay1.layer.zPosition = 1
(UIApplication.shared.delegate as? AppDelegate).window.addSubview(overlay1)
After discussion in comments found that changing the backgroundColor of statusBar is the reason why your code is not working properly.
By printing the superView of statusBar I found that statusBar is not added on UIWindow instead it is on UIStatusBarWindow which is probably above the mainWindow.
Also please don't use force unwrapping it can be cause of crash. At last I put a guard to fetch the statusBar, to check if it responds to backgroundColor property, to fetch its superView and adding the overlay on this superView got it working.
Your check for respondToSelector is also wrong. See below code it works as per your requirement.
guard let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView, statusBar.responds(to: NSSelectorFromString("backgroundColor")), let superView = statusBar.superview else {return}
statusBar.backgroundColor = UIColor.red
let overlay1 = UIImageView(image: UIImage(named: "overlay-image"))
overlay1.contentMode = .scaleAspectFit
overlay1.backgroundColor = UIColor.black
overlay1.alpha = 0.87
overlay1.frame = superView.bounds
overlay1.isUserInteractionEnabled = true
overlay1.layer.zPosition = 1
superView.addSubview(overlay1)
Note: Changing the statusBar color is not recommended. You can set its style to default or light.
Okay I just tried with something and it worked. Just use it in your ViewController like:
// You should be using viewDidAppear(_:)
override func viewDidAppear(_ animated: Bool) {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate, let window = appDelegate.window {
let windowFrame = window.frame
let imageView = UIImageView(frame: windowFrame)
imageView.image = #imageLiteral(resourceName: "TakeOff") // use your image
imageView.contentMode = .scaleAspectFit
imageView.backgroundColor = UIColor.green.withAlphaComponent(0.2) // replace green with the color you want
window.addSubview(imageView)
}
}
But, remember one thing. It's not a good idea to add an image view as
an overlay. You should always use a UIView as an overlay and add the
image view as a sub view to that overlay.
Screenshot:

Show UIImage inside UITextfield, tried but doesn't work

I am using xcode8.3 and Swift3 in my project.
I have a UITextField in storyboard, I created a IBOutlet in corresponding controller class:
#IBOutlet weak var myTextField: UITextField!
I would like to show a small image on the right side inside the text field, I found a solution here (though it shows image on left side).
THis is what I tried:
override func viewDidLoad() {
super.viewDidLoad()
let imageView = UIImageView();
let image = UIImage(named: "my_icon");
imageView.image = image;
self.myTextField.rightView = imageView
self.myTextField.rightViewMode = .always
}
(In xcode Assets.xcassets folder I have my_icon.png, my_icon#2x.png, my_icon#3x.png)
When I run the code on iPhone, I don't see my_icon showing anywhere in UITextField. I also tried to add the ".png" suffix when loading image let image = UIImage(named: "my_icon.png");, it doesn't help either.
Why the solution in the link doesn't work for me?
I had similar issue, it sounds funny but it can cause the issue. I believe your imageView's frame is 0.
So
let imageView = UIImageView();
let image = UIImage(named: "my_icon");
imageView.image = image;
imageView.frame = CGRect(x: 0, y: 0, width: imageView.intrinsicContentSize.width, height: imageView.intrinsicContentSize.height)
self.myTextField.rightView = imageView
self.myTextField.rightViewMode = .always
Set frame:
imageView.frame = CGRect(x: 0, y: 0, width: 20, height: 20)

image and string in same label in swift 2

I have image and string in label togher in navigation bar
When I use coins, say use all 50 of them it should be 0 with image coins but its not
but when I click to another viewcontroller and back to same viewcontroller with coins the image is back
here is code:
let coinLabel = UILabel()
override func viewWillAppear(animated: Bool) {
// Set icon in label in navigation bar ////
let image = UIImage(named: "coins.jpeg")
let newSize = CGSize(width: 15, height: 15)
//Resize image
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
image?.drawInRect(CGRectMake(0, 0, newSize.width, newSize.height))
let imageResized = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//Create attachment text with image
let attachment = NSTextAttachment()
attachment.image = imageResized
let attachmentString = NSAttributedString(attachment: attachment)
let myString = NSMutableAttributedString(string: "\(coins)")
myString.appendAttributedString(attachmentString)
coinLabel.attributedText = myString
coinLabel.sizeToFit()
// Set defined label to navigation bar right corner
let leftItem = UIBarButtonItem(customView: coinLabel)
self.navigationItem.rightBarButtonItem = leftItem
coinLabel.font = coinLabel.font.fontWithSize(15)
}
I think the problem is with reloading... or something. Any Idea??
Don't sure that it's a reason but at least you need to set font before calling sizeToFit()
coinLabel.font = coinLabel.font.fontWithSize(15)
coinLabel.sizeToFit()
Also you missed call to super.viewWillAppear(animated)

How to center an image in navigationBar across all UIViewControllers? Swift / Obj-C

Problem visually:
I have tried putting the image in the center of its own frame with no luck. I have also tried to center it with playing the x of the CGRect with no luck either. I presume I can just put an empty icon with the same background as the navigation bar; however, I don't want to do it that way. I might have 2-3 icons on the right; then what?
let image = UIImage(named: "some_logo")!
let imageSize = CGSizeMake(60, 42)
let marginX: CGFloat = (self.navigationController!.navigationBar.frame.size.width / 2) - (imageSize.width / 2)
let imageView = UIImageView(frame: CGRect(x: marginX, y: 0, width: imageSize.width, height: imageSize.height))
imageView.image = image
imageView.contentMode = .ScaleAspectFit
self.navigationItem.titleView = imageView
I prefer swift but obj-c solutions are welcomed as well.
Any pointers appreciated.
This app has nothing to do with KIA, it is just some logo I got off the google search, searching "some logo".
I have faced the same issue. Then i tried one code shown below.
override func viewDidAppear(animated: Bool) {
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
imageView.contentMode = .ScaleAspectFit
let image = UIImage(named: "googlePlus")
imageView.image = image
navigationItem.titleView = imageView
}
This Code working fine when i tested with Left & Right Bar Button.
But in my previous code there is no Right Bar Button.
So the image is moving towards right.
For solving this i created a Right Bar Button & change the Tint color to clear color.
So everything seems to be working fine. This is one Temporary Solution for your problem.
The easiest way of doing this is in Interface Builder.
Simply drag a 'NavigationItem' from the object library and place it into your ViewController, then place a UIView where the title goes (ensure you set the background to 'clear')
Then place a UIImageView into that view and set the image in the Attributes Inspector to your required image. Scale your UIImage accordingly and set your your constraints accordingly.
I created an extension for solving this problem using the hint of #idrougge.
In order to center the title view image no matter what buttons you have, a content view is set as title view, then the image view is added as child of the content view. Finally, using constraints the image view is aligned inside its parent (content view).
import UIKit
extension UIViewController {
func addLogoToNavigationBarItem() {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.heightAnchor.constraint(equalToConstant: <your_height>).isActive = true
imageView.contentMode = .scaleAspectFit
imageView.image = <your_image>
//imageView.backgroundColor = .lightGray
// In order to center the title view image no matter what buttons there are, do not set the
// image view as title view, because it doesn't work. If there is only one button, the image
// will not be aligned. Instead, a content view is set as title view, then the image view is
// added as child of the content view. Finally, using constraints the image view is aligned
// inside its parent.
let contentView = UIView()
self.navigationItem.titleView = contentView
self.navigationItem.titleView?.addSubview(imageView)
imageView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
imageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
}
}
I hope this helps someone,
Xavi
As question heading stated "Swift / Obj-C" so I am sharing code of Obj-C :
UIImageView *titleImage = (UIImageView *)self.navigationItem.titleView;
titleImage = [[UIImageView alloc]initWithFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width/2) - (100/2), 0, 100,self.navigationController.navigationBar.frame.size.height)];
//setting the image for UIImageView
titleImage.image = [UIImage imageNamed:#"someLogo"];
titleImage.contentMode = UIViewContentModeCenter;
self.navigationItem.titleView = titleImage;
Had same issue on phones with smaller sizes. Image in title was moving to right. Causing this issue back button -> [back_button][title_view]. Its centered when there is no back button or there is right bar button. Richard Hope's was right, you just need to put UIView first, and then put UIImageView as subview. Programmatically could be done like this.
private var imageView: UIView {
let bannerWidth = navigationBar.frame.size.width * 0.5 // 0.5 its multiplier to get correct image width
let bannerHeight = navigationBar.frame.size.height
let view = UIView()
view.backgroundColor = .clear
view.frame = CGRect(x: 0, y: 0, width: bannerWidth, height: bannerHeight)
let image = UIImage(named: "your_image_name")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
view.addSubview(imageView)
return view
}
The just change titleView
navigationItem.titleView = imageView
What about setting the center of your image equals to the navigationBar.center instead of setting a margin?
//assuming we already have our navigationController
let myNicelLogoWidth = 100
let myNiceLogoHeight = 50
//start positioning your logo at 0.0, 0.0
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: myNicelLogoWidth, height: myNiceLogoHeight))
imageView.contentMode = .scaleAspectFit
imageView.center = navigationBar.center //the put your image at the center
let image = UIImage(named: "myNiceLogoImage")
imageView.image = image
navigationItem.titleView = imageView
I once face with this problem, and finally i found out that the problem is the previous navigation bar title still located next to burger button, but it's invisible.
Fast solution but not sure if it's the best is to change the previous navigation bar title to empty string before show the next view controller.
Hope it's help.

Resources