Displaying a Live Photo, swift [duplicate] - ios

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.

Related

Kingfisher iOS image not loading

I am trying to dynamically set a UIImageView using Kingfisher. The context is there is a TableView on the previous screen of different selectable rows and then when the row is selected a details UIView shows which has more information, including an image. I have gone to the Kingfisher documentation and found that the declaration belongs in the viewDidLoad as i have it but i still cannot get the image to load. I have also verified with debugging that the URL being passed to the Kingfisher is a link to a picture. I am thinking this may have to do with the image being set on a background thread but i am unsure how to fix that if that is the case. I have tried moving the implementation of the Kingfisher to the viewWillAppear and viewDidAppear functions and they still do not display the image even after an extended amount of wait time
Here is my code with some unrelated functionality removed.
import UIKit
import Kingfisher
class DetailsViewController: UIViewController {
#IBOutlet weak var thumbnail: UIImageView!
var thumbnailURL: URL?
override func viewDidLoad() {
super.viewDidLoad()
self.thumbnail.kf.setImage(with: thumbnailURL)
...................................................
// self.thumbnail.image = UIImage(named: "image1")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
kd02 - I have found the answer to my question. When you asked if it was http or https i remembered that you have to enable http in xcode 9 now because of the security enhancement. I did that and now it works.
Try something like this
import UIKit
import Kingfisher
class DetailsViewController: UIViewController {
#IBOutlet weak var thumbnail: UIImageView!
var thumbnailURL: URL?
override func viewDidLoad() {
super.viewDidLoad()
if let url = self.thumbnailURL {
self.thumbnail.setImage(with: url)
}
}
}
I have feeling the optional URL is causing the problem.

Reuse AVPlayer's in TableView

Can anyone help in creating a pool of AVPlayer's to be reused in a tableView? So the idea is to have a pool of AVPlayer's, let's say 3, and continue to reuse them as the user scrolls through the table.
Here's a quick synopsis of the app and what we want to build:
Each video is an mp4 and is only 5 seconds long. So each cell will play a 5 second video and loop it.
All videos are local, they will be downloaded to disk before the table is even shown to the user. This will help in terms of smooth scroll performance of the tableView.
Right now I am creating too many AVPlayer's and not reusing them which is having a bad effect on performance such as scrolling is a bit choppy. Also, Apple does not allow an infinite amount of AVPlayer's to be created.
Any ideas? Thanks
Update 1:
import UIKit
import VIMVideoPlayer
var cache = NSCache<NSString, VIMVideoPlayerView>()
class FeedTableViewCell: UITableViewCell {
// MARK: - Properties
#IBOutlet weak var containerView: UIView!
static let reuseIdentifier = "FeedTableViewCell"
var video: Video? {
didSet {
if let cachedVideoPlayerView = cache.object(forKey: video!.preview!.remoteURL as NSString) {
// We have a cached video player view!
containerView.addSubview(cachedVideoPlayerView)
} else {
// There is nothing cached.
let previewURL = FileManager.applicationDocumentsDirectory.appendingPathComponent(video!.preview!.fileName!)
let newVideoPlayer = VIMVideoPlayer()
newVideoPlayer.setURL(previewURL)
newVideoPlayer.isLooping = true
newVideoPlayer.isMuted = true
newVideoPlayer.disableAirplay()
let newVideoPlayerView = VIMVideoPlayerView()
newVideoPlayerView.frame = contentView.bounds
newVideoPlayerView.delegate = self
newVideoPlayerView.setVideoFillMode(AVLayerVideoGravityResizeAspectFill)
newVideoPlayerView.player = newVideoPlayer
containerView.addSubview(newVideoPlayerView)
cache.setObject(newVideoPlayerView, forKey: video!.preview!.remoteURL as NSString)
}
}
}
// MARK: - Life Cycle
override func awakeFromNib() {
super.awakeFromNib()
print("AWAKE FROM NIB CELL")
}
override func prepareForReuse() {
super.prepareForReuse()
}
}
// MARK: - VIMVideoPlayerViewDelegate
extension FeedTableViewCell: VIMVideoPlayerViewDelegate {
func videoPlayerViewIsReady(toPlayVideo videoPlayerView: VIMVideoPlayerView!) {
videoPlayerView.player.play()
}
}
Extending your idea of using a pool, instead of reinventing the wheel, why not leverage UITableViewCell's current implementation of reusability? At any given time, n 'reusable' UITableViewCells exist, acting as your pool.
If each one of these cells contains a single AVPlayer subview, then the management is done for you by the table view. Therefore in the UITableViewCell's reuse identifier, stop the player (if needed), update its MP4 (from an in-memory cache ideally), and start it again.
If needed, you can cache the position of the video when the cell disappears in order to make it seem like the video never stopped playing while scrolling was in progress.
-- As a side note, theoretically this will work, but has not been tested with a live app. The obvious caveat is the size of the video being loaded into the AVPlayer on the main thread, while attempting to maintain 60fps.
Edit:
Please see https://stackoverflow.com/a/35514126/556479 for more info.

Changing an image using swift for iOS App

So I am trying to load a picture programmatically using Swift and I am having some trouble. I can change the UIImage of a view using the Attributes Inspector, so I know the picture I am using is added properly and I am using the right name.
Here is the code I am using:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myPicture: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
myPicture.image = UIImage(named:"myNewPic")
}
}
I think there might be some setting I am missing in Attributes inspector or something since the code is pretty simple and I know the image is added properly.
Any help would be appreciated.
Make sure that your image name is correct. You have image properly in xcode and your outlet is properly connected
add image with extension if you are not using assets for images. like myNewPic.png or myNewPic.jpg whatever extension it is.
So, your code should be like,
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myPicture: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
myPicture.image = UIImage(named:"myNewPic.png") //or .jpg or else
}
}
another choice
if you load image from assets usemyNewPic if you load from bundle use myNewPic.png (with extensions).
if let img = UIImage(named: "myNewPic") {
myPicture.image = img
} else {
myPicture.image = UIImage(named:"myNewPic.Imageextensions")
}

How to make Image page viewer for images swift ios

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.

How can I stop my swift app from crashing

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 :-)

Resources