UITextField RightView image goes out of bounds - ios

SO I have a textfield which is basically JVFloatLabeledTextField for floating texts and works upon checking if the username is available. If the webservice returns a response object that username already exists the textfields rightview sets a red alert image whereas if it returns that the username is available then the rightview imageview is set to something green.. Well the image is being set a bit out of bounds. I have tried everything.. Attached herewith is the snapshot, and here is the code:
usernameTextField.rightViewMode = UITextFieldViewMode.always
let imageView = UIImageView.init(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
var imageName:String = ""
if jsonReturned["errorCode"] == "Success" {
imageName = "isAcceptedIcon"
} else {
imageName = "isRejectedIcon"
}
let image = UIImage(named: imageName)
imageView.image = image
usernameTextField.rightView = imageView
Any help is greatly appreciated. I want to shift the image to a bit left. Thanks in advance.

SO I kind of solved it on my own. Its kind of very simple infact. Instead of appointing to the rightView, the imageView.. I had to set rightView's frame and then addSubview(imageView) to it. Here's the code and the new attached picture:
userEmailTextField.rightViewMode = UITextFieldViewMode.always
let imageView = UIImageView.init(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
usernameTextField.rightView?.frame = AppManager.shared.CGRectMake(0, 0, 25, 20)
var imageName:String = ""
if jsonReturned["errorCode"] == "Success" {
imageName = "isAcceptedIcon"
} else {
imageName = "isRejectedIcon"
}
let image = UIImage(named: imageName)
imageView.image = image
imageView.contentMode = .scaleAspectFit
usernameTextField.rightView?.addSubview(imageView)
So yeah that was a tremendous fix! Hope this helps someone else too :)

Related

Swift 5: Better way/approach to add image border on photo editing app?

In case the title doesn't make sense, i'm trying to make a photo editing app where user can add border to their photo. For now, i'm testing a white border.
here is a gif sample of the app. (see how slow the slider is. It's meant to be smooth like any other slider.)
Gif sample
My approach was, to render the white background to the image's size, and then render the image n% smaller to shrink it hence the border.
But i have come to a problem where when i'm testing on my device (iphone 7 plus) the slider was so laggy and slow as if it's taking so much time to compute the function.
Here are the codes for the function. This function serves as blend the background with the foreground. Background being plain white colour.
blendImages is a function located on my adjustmentEngine class.
func blendImages(backgroundImg: UIImage,foregroundImg: UIImage) -> Data? {
// size variable
let contentSizeH = foregroundImg.size.height
let contentSizeW = foregroundImg.size.width
// the magic. how the image will scale in the view.
let topImageH = foregroundImg.size.height - (foregroundImg.size.height * imgSizeMultiplier)
let topImageW = foregroundImg.size.width - (foregroundImg.size.width * imgSizeMultiplier)
let bottomImage = backgroundImg
let topImage = foregroundImg
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width : contentSizeW, height: contentSizeH))
let imgView2 = UIImageView(frame: CGRect(x: 0, y: 0, width: topImageW, height: topImageH))
// - Set Content mode to what you desire
imgView.contentMode = .scaleAspectFill
imgView2.contentMode = .scaleAspectFit
// - Set Images
imgView.image = bottomImage
imgView2.image = topImage
imgView2.center = imgView.center
// - Create UIView
let contentView = UIView(frame: CGRect(x: 0, y: 0, width: contentSizeW, height: contentSizeH))
contentView.addSubview(imgView)
contentView.addSubview(imgView2)
// - Set Size
let size = CGSize(width: contentSizeW, height: contentSizeH)
UIGraphicsBeginImageContextWithOptions(size, true, 0)
contentView.drawHierarchy(in: contentView.bounds, afterScreenUpdates: true)
guard let i = UIGraphicsGetImageFromCurrentImageContext(),
let data = i.jpegData(compressionQuality: 1.0)
else {return nil}
UIGraphicsEndImageContext()
return data
}
Below are the function i called to render it into uiImageView
guard let image = image else { return }
let borderColor = UIColor.white.image()
self.adjustmentEngine.borderColor = borderColor
self.adjustmentEngine.image = image
guard let combinedImageData: Data = self.adjustmentEngine.blendImages(backgroundImg: borderColor, foregroundImg: image) else {return}
let combinedImage = UIImage(data: combinedImageData)
self.imageView.image = combinedImage
This function will get the image and blend it with a new background colour for the border.
And finally, below are the codes for the slider's didChange function.
#IBAction func sliderDidChange(_ sender: UISlider) {
print(sender.value)
let borderColor = adjustmentEngine.borderColor
let image = adjustmentEngine.image
adjustmentEngine.imgSizeMultiplier = CGFloat(sender.value)
guard let combinedImageData: Data = self.adjustmentEngine.blendImages(backgroundImg: borderColor, foregroundImg: image) else {return}
let combinedImage = UIImage(data: combinedImageData)
self.imageView.image = combinedImage
}
So the question is, Is there a better way or optimised way to do this? Or a better approach?

Give inset to UIImageView before setting Its frame

I have an UITextField component which has an icon on the right side of it. Icon is just an UIImageView. I'm trying to give inset to UIImageView with below code
imageView.image = UIImage(named: "example")?.withAlignmentRectInsets(UIEdgeInsets(top: -4, left: 0, bottom: -4, right: 0))
However, It doesn't work cuz It's frame hasn't been set when setting Its' Image. I'm giving Its frame with below code;
iconImageView.frame = CGRect(
x: bounds.size.width - iconWidth - iconMarginLeft,
y: bounds.size.height - textHeight() - iconMarginBottom,
width: iconWidth,
height: textHeight()
)
and how I setup UIImageView
fileprivate func createIconImageView() {
let iconImageView = UIImageView()
iconImageView.backgroundColor = .clear
iconImageView.contentMode = .scaleAspectFill
iconImageView.autoresizingMask = [.flexibleTopMargin, .flexibleRightMargin]
if (hasToolTip) {
let tapGesture = UITapGestureRecognizer(target: self, action:#selector(toolTipTapped(_:)))
iconImageView.addGestureRecognizer(tapGesture)
iconImageView.isUserInteractionEnabled = true
let image = UIImage(named: "infotooltip")
image?.accessibilityIdentifier = "tooltipImage"
iconImageView.image = image!
changeIconAlphaToOne()
self.iconImageView = iconImageView
} else {
self.iconImageView = iconImageView
changeIconAlphaToZero()
}
addSubview(iconImageView)
}
My problem is that, I need to give UIEdgeInset to the image. However, because I'm trying to give it before setting the frame, It doesn't work. How can I achieve this?
I also try to resize the image by referencing below post but doesn't work for me. I also DO NOT want to put it inside a content view which will make my component class more complicated.
The simplest way to resize an UIImage?

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.
}

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)

iOS swift how to place an imageview in a uiview exactly

I have an issue, I'm creating an imageView programmatically and then add it to a center view, which is kind of working. But the problem is that is not taking the whole space in the center view, it appears yes in the uiview but not covering all always a bit down. Any help?
The code:
//let backgroundImage = UIImageView(frame: centerView.frame)
let backgroundImage: UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.centerView.bounds.size.width, height: self.centerView.bounds.size.height))
print("backgorundImage coordinates: \(backgroundImage.frame)")
backgroundImage.image = drawOverImage
backgroundImage.sizeThatFits(CGSizeMake(centerView.bounds.width, self.centerView.bounds.height))
//check this the image is being drawn bottom because is the fame for the previous 0.0
//backgroundImage.autoPinEdgeToSuperviewMargin(ALEdge.Top, relation: NSLayoutRelation.Equal)
//backgroundImage.contentMode = UIViewContentMode.ScaleAspectFill //too big
//backgroundImage.contentMode = UIViewContentMode.ScaleAspectFit //sama
backgroundImage.contentMode = UIViewContentMode.ScaleAspectFill
backgroundImage.clipsToBounds = true
//imageView.image = background
backgroundImage.center = view.center
let coordinatesForImage: CGRect = self.view.convertRect(backgroundImage.frame, toView: centerView)
let pointOfImage: CGPoint = backgroundImage.convertPoint(self.centerView.frame.origin, toView: backgroundImage)
print("coordinates test: \(coordinatesForImage)")
print("point x: \(pointOfImage.x)")
print("point y: \(pointOfImage.y)")
//backgroundImage.contentMode = UIViewContentMode.ScaleToFill
self.centerView.insertSubview(backgroundImage, atIndex: 0)
let pointOfImageToSuperView: CGPoint = (backgroundImage.superview?.convertPoint(backgroundImage.center, toView: self.centerView))!
print("superview imagepoint: \(pointOfImageToSuperView)")
The comments are all the thing I'm trying to do.
EDIT:
This is what is happening.
I missing a little bit from the bottom, now I don't know if is the size of the image or what, could i change the size of the uiview to match the image?
Simply try:
let backgroundImage: UIImageView = UIImageView(frame: self.centerView.bounds)
backgroundImage.clipsToBounds = true
backgroundImage.contentMode = .ScaleAspectFill
self.centerView.addSubview(backgroundImage)

Resources