I got here such an error:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
What is wrong with my code? I try to add image to navcontroller , I have here image as you can see.
func addNavBarImage() {
let nc = navigationController!
let image = UIImage(named: "2.png")
let imageView = UIImageView(image: image)
let bwidth = nc.navigationBar.frame.size.width
let bheight = nc.navigationBar.frame.size.height
let bannerx = bwidth/2 - (image?.size.width)!/2
let bannery = bheight/2 - (image?.size.height)!/2
imageView.frame = CGRect(x: bannerx, y: bannery, width: bwidth, height: bheight)
imageView.contentMode = .scaleAspectFit
navigationItem.titleView = imageView
}
You get this error message when you don´t have a legit image added to your let image = UIImage(named: "2000"). It is nil. Your code crashes on let bannerx = bwidth/2 - (image?.size.width)!/2. Make sure you have the right image before you continue your execution after that row.
Replace:
let image = UIImage(named: "2.png")
With:
guard let image = UIImage(named: "2") else { return }
By doing this you don´t need the to force optional use the following rows, so replace the below rows for bannerx and bannery with yours:
let bannerx = bwidth/2 - (image.size.width)/2
let bannery = bheight/2 - (image.size.height)/2
Related
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?
I just want to show image according to image size if the image height is grater then width then image will show horizentally or if the width is grater then height then it will show in centre.
I have already tried and I am showing my code. What I am trying ?
override func viewDidLoad() {
super.viewDidLoad()
var profileImagesData:Array<UIImage> = []
for i in 0..<profileImages.count {
// for venueImageTemp in profileImages {
var statusDict = profileImages[i] as! Dictionary<String,Any>
var imageUrl = String(format:"%#",statusDict["imageId"] as! CVarArg)
print(imageUrl)
if imageUrl.contains("cloudinary.com") {
let imgNameArr = imageUrl.components(separatedBy: "upload/")
print(imgNameArr)
let subFisrtStr = imgNameArr[0]
print(subFisrtStr)
let subStr = imgNameArr[1]
print(subStr)
let subImgNameArr = subStr.components(separatedBy: "/")
print(subImgNameArr)
let subNameStr = subImgNameArr[1]
print(subNameStr)
imageUrl = ""
imageUrl = subFisrtStr + "upload/h_600,w_600/" + subNameStr
print(imageUrl)
}
let url = URL(string: imageUrl)
print(url)
let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in
let image = UIImage(data: (data)!)
profileImagesData.append(image!)
}
let imageView = CYCImageScrollView(images: profileImagesData, frame: CGRect(x: 0, y: 20, width: self.view.frame.size.width, height: self.view.frame.size.height-150), pageColor: UIColor.lightGray, currentPageColor: UIColor.orange)
// imageView.layer.cornerRadius = 30
imageView.backgroundColor = UIColor.clear
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
imageView.layer.masksToBounds = true
self.view.addSubview(imageView)
}
I just want to show image according to their sizes.
Use content mode scaleAspectFill instead of scaleAspectFit
imageView.contentMode = .scaleAspectFill
I'm trying to register a tap inside an UIScrollView but can't seem to get it work. I tried everything I've found on here to no success. I'm using a subclass of UIImageView to add an identifier to it which shouldn't be the problem. Can't seem to get it to work with the default UIImageView class either. "didTapImage" just does not get executed no matter what I do.
func fillSelectionView(){
let imageNameArray = ["entdecken", "erleben", "erinnern"]
imageArray = [UIImage(named: imageNameArray[0]), UIImage(named: imageNameArray[1]), UIImage(named: imageNameArray[2])] as! [UIImage]
for i in 0..<imageArray.count{
let imageView = UIImageViewWithIdentifier()
imageView.image = imageArray[i]
imageView.contentMode = .scaleAspectFit
imageView.setIdentifier(ident: imageNameArray[i])
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(UIGestureRecognizer(target: self, action: Selector(("didTapImage"))))
let xPosition = self.selectionView.frame.width * CGFloat(Double(i))
imageView.frame = CGRect(x: xPosition, y: 0, width: selectionView.frame.width, height: selectionView.frame.height)
selectionView.contentSize.width = self.selectionView.frame.width * CGFloat((Double(i) + 1))
selectionView.addSubview(imageView)
}
}
func didTapImage(gesture: UIGestureRecognizer) {
let point = gesture.location(in: gesture.view)
let imageViewTouched = gesture.view as! UIImageViewWithIdentifier
let imageViewIdent = imageViewTouched.getIdentifier()
print(point)
print("touched" + imageViewIdent)
}
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
I've centered my Image and my label in the footer of my tableView like this :
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
switch section {
case 2:
let view = UIView()
let version = UILabel(frame: CGRectMake(0, 40, tableView.frame.width, 30))
version.font = version.font.fontWithSize(14)
version.text = Constants.Version
version.textColor = UIColor.lightGrayColor()
version.textAlignment = .Center;
let logo = UIImageView(frame: CGRectMake(0, 15, tableView.frame.width, 30))
logo.contentMode = .ScaleAspectFit
logo.image = UIImage(named: "LogoVector")
let context = CIContext(options: nil)
if let currentFilter = CIFilter(name: "CISepiaTone") {
let beginImage = CIImage(image: logo.image!)
currentFilter.setValue(beginImage, forKey: kCIInputImageKey)
currentFilter.setValue(0.5, forKey: kCIInputIntensityKey)
if let output = currentFilter.outputImage {
let cgimg = context.createCGImage(output, fromRect: output.extent)
let processedImage = UIImage(CGImage: cgimg)
logo.image = processedImage
}
}
view.addSubview(version)
view.addSubview(logo)
return view
default:
return nil
}
}
But when I'm going on the view, I have something like a freeze while the image is loading.. Do you have any idea?
regards.
You are paused while you are doing the filtering. Since you've hardcoded an image there, I'd suggest you add the sepia tone to the image directly with an image editor and save that. Then you're not doing that processing at run time every time.
If that's not an option, you could just create/position the toplevel UIImageView in this method, and then do a dispatch_async() to create the image and apply the filter, and then when it's done update the image view