I am new to Swift programming and really have high hopes from all the experts out there. While creating a simple app I ran into memory issues and my app crashed. Below are more details about my app..
My app has an image view, three images and three buttons in toolbar. All my app does right now is changes image with button press. Example if you press say button1, it will load image1, if you press button2 it would load image 2 and if you press button 3 it would load image 3.
This app crash after 1 cycle, like I can tap all the three buttons and it would work, however if I tap on any button after that it would just crash.
I am testing this on iPad mini. Works perfectly fine on simulator. Any help would be greatly appreciated. I head somewhere that UIImage (named:) can be an issue, but I don't know how to replace that with anything else in Swift.
Here is the code for it
import UIKit
class ViewController: UIViewController
{
#IBOutlet weak var TestImage: UIImageView!
#IBAction func Button1(sender: AnyObject)
{
TestImage.image = UIImage (named: "Image1.jpg")
}
#IBAction func Button2(sender: AnyObject)
{
TestImage.image = UIImage (named: "Image2.jpg")
}
#IBAction func Button3(sender: AnyObject)
{
TestImage.image = UIImage (named: "Image1.jpg")
}
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The problem with UIImage(named: name) is that it caches the images. As the documentation says:
If you have an image file that will only be displayed once and wish to ensure that it does not get added to the system’s cache, you should instead create your image using imageWithContentsOfFile:. This will keep your single-use image out of the system image cache, potentially improving the memory use characteristics of your app.
Thus, if you have memory problems arising from the size/number of images in the system cache, you can use UIImage(contentsOfFile: path) rather than UIImage(named: name):
if let path = NSBundle.mainBundle().pathForResource("Image1", ofType: "jpg") {
TestImage.image = UIImage(contentsOfFile:path)
}
I reduced the size using png 8 format in ps and it fixed the issue for me.. Thanks all for your help :-)
Related
I'm new to swift and I've searched different places and couldn't really find anything helpful.
I am in this case that I pick an image from UIImagePickerController when pressing on the button:
#IBAction func chooseImage(_ sender: Any){}
which works and I can access the photo library and choose an image but..
the thing is that I want to set it to the button image.
I save the image to:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
// this works with an UIimageView.image but I can't get it to work with the button
???.image = image
I believe the way to do it is to say; button.ImageView.image = image and this can only be done by creating a variable called UIButton!??
and then I can set
button.ImageView.image = image
otherwise I can't enter the method ImageView.image
But the thing is that chooseImage is the same button I use for the action of receiving the image... So can I both make a #IBOutlet weak var button: UIButton! and #IBAction on the same button??
Well I tried and created both a
#IBOutlet weak var button: UIButton!
and
#IBAction func chooseImage(_ sender: Any) {
button.imageView.image = image
}
but nothing happened It might sound confusing,but there is two questions. Is it possible to do it this way? and if yes, why isn't the picture being shown when doing
button.imageView.image = image?
and if not please tell me what im doing wrong :-)
Thanks!
someButton.setImage(imagenew, for: .normal)
There is a setimage method for UIButton. you can also set image as background image. There is a method called setbackgroundImage.
try this
button.setImage(image, for: .normal) // Swift 3
Use setImage() method to set the foreground image of a button. However, if your buttons are all blue, that's because there is a feature for images called "Rendering Mode" you should be aware of, please refer to Template Images for more information:
button.setImage(image.withRenderingMode(.alwaysOriginal), for: .normal)
This question already has an answer here:
Working with Live Photos in Playground
(1 answer)
Closed 6 years ago.
I have the following ViewController class I am trying to get to display a live photo. I am not precisely sure how to actually get the image to show In dealing with a UIImageView I would write something like this:
let image = UIImage(imageNamed: "someStringPointingToImage") //then add this to the image view.
But does anyone know how it works with a live image that I have added in my assets?
The function
import UIKit
import Photos;
import PhotosUI
import MobileCoreServices
class ViewController: UIViewController, PHLivePhotoViewDelegate {
var livePhotoIsAnimating = Bool()
override func viewDidLoad() {
super.viewDidLoad()
self.livePhotoView()
}
//MARK: Create the Live Photoview
func livePhotoView() {
let photoView: PHLivePhotoView = PHLivePhotoView.init(frame: self.view.bounds)
//%%%%%%% Area to add the image %%%%%%
photoView.contentMode = .ScaleAspectFill
self.view.addSubview(photoView)
self.view.sendSubviewToBack(photoView)
}
func livePhotoView(livePhotoView: PHLivePhotoView, willBeginPlaybackWithStyle playbackStyle: PHLivePhotoViewPlaybackStyle) {
self.livePhotoIsAnimating = true
}
func livePhotoView(livePhotoView: PHLivePhotoView, didEndPlaybackWithStyle playbackStyle: PHLivePhotoViewPlaybackStyle) {
self.livePhotoIsAnimating = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thanks.
Live Photos are a construct of the Photos app. The only place you can get a Live Photo is from the Photos framework (which, in turn, gets it from the user's Photos library). There's no affordance for storing Live Photos as bundle resources in your app.
If you want to present animated images, just use the UIImage constructors that create animated images from a set of frames, and display them in a UIImageView. Add your own gesture recognizers and you can easily create a UI that presents a static image by default and an animated one when tapped/pressed/whatever.
If you want to present video, look into AVKit.
In my app I am setting the image of a UIImageView as follows:
override func viewWillAppear(animated: Bool) {
// ...
self.currentPlayer.image = UIImage(named: appDelegate.appSupportDirectory.stringByAppendingPathComponent(currentPlayer!.id!.UUIDString + ".jpg"))
}
In a different view, I allow the user to change the image, namely replace the file with a new one while keeping the name. When I return to this view the old picture is still shown. The app seems to remember the outdated picture even when I load a different player profile in between. How can I force the UIImageView to refresh?
Solution found. Change the code to:
override func viewWillAppear(animated: Bool) {
// ...
self.currentPlayer.image = UIImage(contentsOfFile: appDelegate.appSupportDirectory.stringByAppendingPathComponent(currentPlayer!.id!.UUIDString + ".jpg"))
}
I've been working on a set of iOS action extensions I seem to be having a problem with the way that the UINavigationBar is being displayed in the app if it is controlled by a UINavigationController.
The problem, in short is that the navigation bar gets shifted up when you rotate from portrait, to landscape, and back to portrait again. The problem is exacerbated if you rotate all the way around. I wish I could provide images, but I cannot given the rules of StackOverflow.
Regardless, this was tested using a only slightly modified Action App Extension (modified to lower target OS, silence a warning about the NSExtensionActiviationRule, etc), both with a UINavigationBar embedded in a UINavigationController and not embedded, just as a view in the ActionViewController. When not in an UINavigationController, the rotations look as expected, but retains a white patch around the status bar (and the navigation bar is slightly wider in the landscape orientation), but when put into a UINavigationController, the bar button items are shifted up.
This was tested pretty thoroughly in 8.2, and even now running the slightly modified app, it looks as one would expect. Does anyone know exactly going on here? Why does the button get shifted up when I use a UINavigationController in 8.3 and not 8.2? I can't seem to find any documentation on a change in 8.3 that would affect it, and no documentation that UINavigationController shouldn't be used in an Action Extension, etc. Any help would be greatly appreciated.
Here is the code, if you are interested, for the ViewController. Its not particularly enlightening, as it's basically what Apple gives you:
import UIKit
import MobileCoreServices
class ActionViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Get the item[s] we're handling from the extension context.
// For example, look for an image and place it into an image view.
// Replace this with something appropriate for the type[s] your extension supports.
var imageFound = false
for item: AnyObject in self.extensionContext!.inputItems {
let inputItem = item as! NSExtensionItem
for provider: AnyObject in inputItem.attachments! {
let itemProvider = provider as! NSItemProvider
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
// This is an image. We'll load it, then place it in our image view.
weak var weakImageView = self.imageView
itemProvider.loadItemForTypeIdentifier(kUTTypeImage as String, options: nil, completionHandler: { (url, error) in
let imageURL = url as! NSURL?;
if imageURL != nil {
NSOperationQueue.mainQueue().addOperationWithBlock {
if let imageView = weakImageView {
let image = UIImage(contentsOfFile: imageURL!.path!);
imageView.image = image;
}
}
}
})
imageFound = true
break
}
}
if (imageFound) {
// We only handle one image, so stop looking for more.
break
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func done() {
// Return any edited content to the host app.
// This template doesn't do anything, so we just echo the passed in items.
self.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)
}
}
Thanks in advance!
I wanna display a couple of images from the assets folders, into my application. so I wanna make a page view.
First, images will be inside collection view, then on click, the image will be full screen. Then the user can slide between the images by swiping right and left as shown in the following photo:
I found this tutorial:
PhotosGalleryApp
Updated:
I have this in my storyboard:
Now in GaleryViewController I show the images in cells
when user click on it, I open the image in fullscreen in PhotoViewController.
PhotoViewController.swift :
import UIKit
class PhotoViewController: UIViewController{
#IBOutlet weak var imageView: UIImageView!
var index: Int = 0;
var pageViewController : UIPageViewController?
#IBAction func btnCancelClicked(sender: AnyObject) {
self.navigationController?.popToRootViewControllerAnimated(true);
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initUI();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
self.navigationController?.hidesBarsOnTap = true;
self.navigationController?.hidesBarsOnSwipe = true;
displayPhoto()
}
func initUI() -> Void {
// pageViewController = UIPageViewController(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: nil)
// pageViewController!.dataSource = self
}
func displayPhoto() {
self.imageView.image = UIImage(named: Constants.Statics.images[index])
}
I have the images in static structure so i can access them anywhere:
class Constants {
struct Statics {
static let images = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","7.jpg","8.jpg"]
}
}
My problem is: I want to add the feature that allow me to swipe between pictures inside the PhotoViewController.
Any ideas?
Thank you
You can do one of the following two things to achieve your goal :
Make a modal segue of the cell to the next UICollectionViewController where the images are showed in full screen, and in the prepareForSegue pass all the data (images) you need to show and where exactly you are in this moment (indexOfImage).
You can watch the didSelectItemAtIndexPath and then pass all the data to one instance of the next UICollectionViewController you want to show with the presentViewController func.
But it's very important that in the next UICollectionViewController you have set pageEnabled = true in code or in the Interface Builder (I though is much easy to do.)
UPDATE:
Very good tutorials on how to make a slide show of images using an UIScrollView or an UICollectionView :
How To Use UIScrollView to Scroll and Zoom Content
Creating a Paged Photo Gallery With a UICollectionView
I hope this help you.