UIImageView: How to show scaled image? - ios

I'm new to iOS app development and I begun to learn from this great tutorial:
Start Developing iOS Apps (Swift)
https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/WorkWithViewControllers.html#//apple_ref/doc/uid/TP40015214-CH6-SW1
Everything looks great but when trying to load an image from "Camera roll" on the simulator, I get the image shown oversized and filling all the iPhone simulator screen instead of just showing into the UIImageView box as shown on tutorial images.
The funny fact is that also downloading the correct project provided at the end of the lesson (see the bottom of the page) I get the same issue.
Googling around I get some ideas to insert a:
// The info dictionary may contain multiple representations of the image. You want to use the original
guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
// Set photoImageView to display the selected image
photoImageView.image = selectedImage
photoImageView.contentMode = UIViewContentMode.scaleAspectFit
// Dismiss the picker
dismiss(animated: true, completion: nil)
after loading image from the camera roll, but lead to no results...
I'm using Xcode 9.2 with deployment target 11.2 and iPhone 8 plus as a target for the simulator.
Any help is apreciated.

It happens because the sample code is only restricting the proportion of the UIImageView (the 1:1 constraint you added in storyboard). In this way, it will always keep your imageView squared but will not limit the size.
As the sample tells, you entered a placeholder size, that is only kept until you set some image on it. When you enter a new image on the UIImageView it changes to the size of the image you set (in your case, probably a bigger image for the camera roll). That's probably why its getting so large.
I think the easy way to fix this to add other constraints in storyboard to limit the size (like actually size or border constraints).

Related

Use launch image set on UIImageView

I am creating instruction screen for my app where I have to place a full screen sized image. For that purpose I have to consider all screen sizes and thus I have created a Launch image set in AssetCatalog.
On the view, I have UIImageView. On setting the image for the UIImageView, I get a white screen. I am guessing launch image can't be set on UIImageView.
What might be the best approach here ?
Note : Please share your answers considering the latest naming conventions (including iPhone X) if required.
The launch screen is just like a regular storyboard. You can add an image view controller, text labels, or other UIKit controls.
I'd recommend against using a static image for the launch screen for a variety of reasons.
It can't be localized.
It may distort based on the screen resolution and orientation of the device.
Instead, treat the launch screen as any other view controller. Add controls, images, and static text along with the appropriate layout constraints. This approach will give you a lot more flexibility and scale better.
If you really want to add the static image, add a UIImageView control to the launch view controller and set its dimensions to the extents of the view. Then, assign the image to the image view control.
You can not directly use the Launch Images. I found a workaround:
func getLaunchImageName() -> String? {
// Get All PNG Images from the App Bundle
let allPngImageNames = Bundle.main.paths(forResourcesOfType: "png", inDirectory: nil)
// The Launch Images have a naming convention and it has a prefix 'LaunchImage'
let expression = "SELF contains '\("LaunchImage")'"
// Filter the Array to get the Images with the prefix 'LaunchImage'
let res = (allPngImageNames as NSArray).filtered(using: NSPredicate(format: expression))
var launchImageName: String = ""
// Now you have to find the image for the Current Device and Orientation
for launchImage in res {
do {
if let img = UIImage(named: (launchImage as? String ?? "")) {
// Has image same scale and dimensions as our current device's screen?
if img.scale == UIScreen.main.scale && (img.size.equalTo(UIScreen.main.bounds.size)) {
// The image with the Current Screen Resolution
launchImageName = launchImage as? String ?? ""
// You can store this image name somewhere, I have stored it in UserDefaults to use in the app anywhere
UserDefaults.standard.set(launchImageName, forKey: "launchImageName")
break
}
}
}
}
return launchImageName
}
I think you created a launch screen and use imageview in it.
If you use it then you must put a image in main bundle not in Assets because assets will not call on launch time. use mainbundle image.
Hope it will help you.
In your LaunchVC take a full size UIImageView
Put your set of images in the in a single resource folder as Resources-> Images.
Put all images in AssetCatalog as you already done. For this you must have 1x, 2x, 3x images sizes to show images in AssetCatalog.
I don't think it is possible that you have image either in bundle or in Asset Catlog and there is no typo for image name and still you don't get image.
Without knowing the image, its hard to tell.
One way could be to simply use a SVG file (or in terms of iOS a PDF Vector file) and just use a image asset with the Scales set to single scale.
If you have a image that is not "scalable" because of text or other stuff, you might need to consider building it yourself in iOS with labels and imageViews.
I think you need new launch screen for displaying your launch image. For this you create new storyboard and change default launch screen to your new launch screen in targets. See this image
Here in Launch Screen File change select your new launch screen. This new launch screen can access your image files from assets.
In so many situations if we want to display animations in splash screen we follow this approach. Try this approach it can solve your problem.

Navigation bar button image coming out pixelated

I'm trying to use a UIImage for my left bar button on my navigation controller. In the design file the button is 40X40px. This ends up being too big to be used for the button. As seen below:
I reduced the button down to 16px and now I get something like this:
I can't seem to get the size right for the button to look clear. I've tried 28px-10px. Any advice?
EDIT Added 10px, 20px, and 30px of image
Code for setting button
var settingsImage = UIImage(named: "SettingsButton10px.png")
settingsImage = settingsImage?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
let settingsButton : UIBarButtonItem = UIBarButtonItem(image: settingsImage, style: UIBarButtonItemStyle.Plain, target: self, action: #selector(HomeController.settingsPressed))
self.navigationItem.leftBarButtonItem = settingsButton
In your projects Assets.xcassets, create an Image Set and provide #1x, #2x and #3x versions. So if the original image size is 20x20, you also need a 40x40, and a 60x60.
Then, when you reference the image in a UIImage, do it with the name of the Image set from the Assets.xcassets without the file extensions. So if the name of the ImageSet in Assets.xcassets was SettingsIcon, you would load the image like so:
UIImage(named: "SettingsIcon")
If adding #2x & #3x image size does't helped you why can't we go with Vector pdf..? Here is what i have got
You can get PDF images from here,Change the image formate from PNG to PDF.
Then in drag and drop the downloaded pdf image in Assets.xcassets. Then Change Scale Factors to Single Vector
3.Make sure Image set look like this
Since we added the image in Assets no need to add extension so replace this
var settingsImage = UIImage(named: "SettingsButton10px.png")
with
var settingsImage = UIImage(named: "SettingsButton10px")
RESUT:
Using PNG 25px:
Using PDF 25px:
So now no need to add double and triple sized images,Pixalation issue will be fixed when we use PDF.
Apple has some information on custom icon sizes here: https://developer.apple.com/ios/human-interface-guidelines/graphics/custom-icons/
The size you want for an iPhone 5 is "About 44px by 44px," so you've got that in the right ballpark. It's a matter of making sure iOS knows this is a retina resolution asset.
The easiest way to do this is putting it in an "Image Set" inside Assets.xcassets. These are containers for multiple different scales, and allow iOS to pick the appropriate version for a given device and display it without pixelation.
The "1x" scale was used in pre-retina devices, "2x" is most common (and is what you'll need to set for the iPhone 5 simulator), and "3x" is for iPhone 6 Plus sized phone.
If you haven't created the 3x image yet, it's fine to leave it blank for now.

Image copied to clipboard is cropped when pasted

I'm building a keyboard extension in Swift (Xcode 7.0.1, iOS 9.0.2). Since images cannot be directly inserted into the text field, I'm using UIPasteboard to copy the image from the app and then the user would paste manually into the text field. I have already modified info.plist to give the app full permission. I initially tried
UIPasteboard.generalPasteboard().image = UIImage(named: "1.png")
but I would receive the error
changing property masksToBounds in transform-only layer, will have no effect
I wasn't able to find anything to fix this error and nothing would be pasted into the clipboard. I then tried
let image = UIImage(named: "1.png")
let data = NSData(data: UIImagePNGRepresentation(image!)!)
UIPasteboard.generalPasteboard().setData(data, forPasteboardType: "public.png")
This works perfectly for larger images, but smaller images are cropped on the right side.
1) Is there a way to programmatically resize the image as a UIImage before I send it to NSData?
2) Has anyone else experienced this issue or know why it's occurring? I'd ideally like the photos being pasted to be small but this is obviously problematic.
Thanks.
I haven't found a proper solution, but adding some transparent padding to the right edge of the image is an effective workaround.

Swift - force square photo from library and camera

I'm building an app and I need to FORCE the user to upload square pictures (just like Instagram does), however I'd like to avoid programming an interface from scratch as we're short in time.
It is important to note that the USER must CHOOSE which part of the image he/she wants to show, so cropping the image programatically without asking the user is out of the question.
I've managed to get this to work via camera, however via library I can't seem to force the user to use a square image. Here's the code I have:
func presentGallery(){
// from library
picker.allowsEditing = true
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
presentViewController(picker, animated: true, completion: nil)
}
Then on my imagepickercontroller:
var chosenImage = info[UIImagePickerControllerEditedImage] as! UIImage
However I don't get the desired result. It would be fine if the "minimum zoom" was to show 100% of the height of the image, or if I could add a white/black background to the top and bottom of the image.
Here's the problem:
Instead of something like this:
My app needs to work starting from iOS7.
You should do some sort of check to make sure that the picture is square if they're picking from their library.
Once you get the image (using imagePickerController didFinishPickingMediaWithInfo), then get the image with [info objectForKey:UIImagePickerControllerOriginalImage];. Once you've done this, perform the check:
if (image.size.height != image.size.width) // Show some alert
What might be an even better solution is creating a view which allows the user to pick any photo, and then choose a square part of the photo to import into your app, like Instagram does.

UIImage looks different when used in iOS

I am having problems with a png image, that gets wrong colors on iOS compared to the actual image.
It does not matter how I am using the image, it always gets the wrong colors. I have tried on UIButton and UIImageView and it gives the same result.
It is a very standard use of a UIImage:
UIImage* greenButtonImg = [UIImage imageNamed:#"btn_green"];
UIImageView* testView = [[UIImageView alloc] initWithImage:greenButtonImg];
[self.view addSubview:testView];
The second image is how it looks on iOS and the first button is how it looks on my Mac (Finder and Photoshop):
As you can see the second button has a different green color.
This is happening all over the app where am using this picture. It happens in the Simulator and on a iPhone 5.
What can cause this issue? Can this be caused by settings in Photoshop, where the image was created?
As Jeff wrote in a comment it was a problem with the RGB Profiles.
I managed to fix the problem by converting the color profile in Photoshop:
Edit -> Convert to Profile... -> Set profile to "Apple RGB"
In iOS 7.0, the image is colored with the toolbar’s tintColor.
In iOS 7.0, all subclasses of UIView derive their behavior for tintColor from the base class.
By default, an image (UIImage) is created with UIImageRenderingModeAutomatic.
If you have UIImageRenderingModeAutomatic set on your image, it will be treated as template or original based on its context.
Certain UIKit elements—including navigation bars, tab bars, toolbars, segmented controls—automatically treat their foreground images as templates, although their background images are treated as original.
Other elements—such as image views and web views—treat their images as originals. If you want your image to always be treated as a template regardless of context, set UIImageRenderingModeAlwaysTemplate.
If you want your image to always be treated as original, set UIImageRenderingModeAlwaysOriginal.
Refer Template Images for more info.

Resources