How to show gif into UIImageView in Swift? - animation

I want use a gif in UIImageView, but I can't.
My code is:
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [[NSBundle mainBundle] URLForResource:#"test" withExtension:#"gif"];
UIImage *testImage = [UIImage animatedImageWithAnimatedGIFData:[NSData dataWithContentsOfURL:url]];
self.dataImageView.animationImages = testImage.images;
self.dataImageView.animationDuration = testImage.duration;
self.dataImageView.animationRepeatCount = 1;
self.dataImageView.image = testImage.images.lastObject;
[self.dataImageView startAnimating];
}
Swift:
var url : NSURL = NSBundle.mainBundle().URLForResource("MAES", withExtension: "gif")
In objective C I had animatedImageWithAnimatedGIFData but in swift I don't know how call this or if not exists..
Thanks!

I assume you're using https://github.com/mayoff/uiimage-from-animated-gif for +UIImage animatedImageWithAnimatedGIFData: and the source code is in Objective-C.
You'll need to first import your Objective-C headers into Swift. Using Swift with Cocoa and Objective-C explains how to do this:
To import a set of Objective-C files in the same framework target as your Swift code,
you’ll need to import those files into the Objective-C umbrella header for the
framework.
To import Objective-C code into Swift from the same framework
Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to Yes.
In your umbrella header file, import every Objective-C header you want to expose to Swift. For example:
#import "UIImage+animatedGIF.h"
You can then setup your testImage as follows:
var testImage = UIImage.animatedImageWithAnimatedGIFData(
NSData.dataWithContentsOfURL(url))
self.dataImageView.animationImages = testImage.images
self.dataImageView.animationDuration = testImage.duration
self.dataImageView.animationRepeatCount = 1
self.dataImageView.image = testImage.images.lastObject
self.dataImageView.startAnimating()

Related

XCUITest detect UIView

So in XCUITest I use this code to get a button:
XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElement *button = app.buttons[#"button_identifier"];
getting a tableview using app.tables and image using app.images and so on.
But how can I get a view(UIView)?
Objective-C
XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElement *customView = app.otherElements[#"view_identifier"];
Swift
let app = XCUIApplication()
let customView = app.otherElements["view_identifier"]
For Swift 3 / 4 it would look like:
let app = XCUIApplication()
let custom_view = app.otherElements["view_identifier"]
Also what I like to do is to have a class variable, as I do reuse these views frequently for different tests:
lazy var custom_view: XCUIElement = { return XCUIApplication().otherElements["view_identifier"] }()

How do I play a video on tvOS for Apple TV?

I started a blank tvOS project and created the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
AVPlayer *avPlayer = [AVPlayer playerWithURL:[NSURL URLWithString:#"http://www.myurl.com/myvideo.mp4"]];
AVPlayerLayer *avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
avPlayerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view.layer addSublayer:avPlayerLayer];
[avPlayer play];
}
Nothing happens in the simulator though once the app loads. No video, nothing, just a blank translucent screen in my Apple TV simulator.
What's the proper way to play a sample video on app launch for an Apple TV app from an HTTP source?
I just pasted your code in my tvOS sample project, replaced the URL and ran it.
Nothing happened. Well, except for the fact that there's a log entry telling me that App Transport Security has blocked my URL request.
So I headed to the Info.plist, disabled ATS and upon next launch the video showed up just fine.
So if you're also using a non-HTTPS URL you're very likely running into this issue which is easily fixed by either using an HTTPS URL, disabling ATS completely or allowing specific non-HTTPs URLs in your Info.plist.
P.S.: I used this video for testing.
You could also use TVML and TVMLJS
https://developer.apple.com/library/prerelease/tvos/documentation/TVMLJS/Reference/TVJSFrameworkReference/
Adhere to the 'TVApplicationControllerDelegate' protocol and add some properties.
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate, TVApplicationControllerDelegate>
...
#property (strong, nonatomic) TVApplicationController *appController;
#property (strong, nonatomic) TVApplicationControllerContext *appControllerContext;
Then add the following to 'didFinishLaunchingWithOptions'
AppDelegate.m
#define url #"http://localhost:8000/main.js"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.appControllerContext = [[TVApplicationControllerContext alloc] init];
NSURL *javascriptURL = [NSURL URLWithString:url];
self.appControllerContext.javaScriptApplicationURL= javascriptURL;
for (id key in launchOptions) {
id val=[launchOptions objectForKey:key];
NSLog(#"key=%# value=%#", key, val);
if([val isKindOfClass:[NSString class]]) [self.appControllerContext.launchOptions objectForKey:val];
self.appController = [[TVApplicationController alloc] initWithContext:self.appControllerContext window:self.window delegate:self];
}
return YES;
}
create a folder and add the following files
main.js
index.tvml
main.js
function launchPlayer() {
var player = new Player();
var playlist = new Playlist();
var mediaItem = new MediaItem("video", "http://trailers.apple.com/movies/focus_features/9/9-clip_480p.mov");
player.playlist = playlist;
player.playlist.push(mediaItem);
player.present();
//player.play()
}
//in application.js
App.onLaunch = function(options) {
launchPlayer();
}
careful with this url in the mediaItem
Set up a template of your choice.
index.tvml
<document>
<alertTemplate>
<title>…</title>
<description>…</description>
<button>
<text>…</text>
</button>
<text>…</text>
</alertTemplate>
</document>
open terminal and navigate to this folder then run
python -m SimpleHTTPServer 8000
make sure the port here is the port in your ObjC url. The Apple examples use 9001.
See these tutorials for more info
http://jamesonquave.com/blog/developing-tvos-apps-for-apple-tv-with-swift/
http://jamesonquave.com/blog/developing-tvos-apps-for-apple-tv-part-2/
One issue I ran into was trying to play a local video file. It wouldn't work and there were constraint issues etc.
It looks like you can't use python to play the videos so either try apache or link to a video on the web.
This SO answer pointed me there.
The best way to play video in your app on AppleTV is going to be AVKit's AVPlayerViewController. If you use AVKit, you get a lot of stuff for free.
https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVPlayerViewController_Class/index.html
You simply add that player to the viewController's player property:
// instantiate here or in storyboard
AVPlayerViewController *viewController = [[AVPlayerViewController alloc] initWithNibName:nil bundle:nil];
viewController.player = player;
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self];
// setup constraints, etc.
// play the video
[player play];
Also as mentioned below, make sure the video you're trying to play is coming either from an HTTPS connection or that you've disabled App Transport Security by setting the proper flags in the plist.
I didn't like the answers which messed about with subviews etc.
For full-screen playback, I use the following (Non-ARC) code:
// Play the stream
NSString *wifiStreamAddress = #"http://yourmoviefile.m3u8";
AVPlayer *player = [[AVPlayer alloc] initWithURL: [NSURL URLWithString: wifiStreamAddress] ];
AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
playerViewController.player = player;
// Keep pointers to player and controller using retained properties:
self.player = player;
self.playerViewController = playerViewController;
[player release];
[playerViewController release];
[self presentViewController: playerViewController animated: true completion: ^{
[self.player play];
}];
This works really neat, animating presentation and fading back to previous view when you tap the MENU button. Also, it works great with the remote control using all the standard functions.
Its working for me.
May be helpful for you
-(void)playAction
{
AVPlayerViewController *viewController = [[AVPlayerViewController alloc] initWithNibName:nil bundle:nil];
viewController.player = player;
[self addChildViewController:viewController];
[self.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self];
// play the video
[player play];
}
Swift version
Make a PlayViewController which inherit the AVPlayerViewController.
In the viewcontroller which has play button, add such function
#IBAction func onClickPlay(sender: AnyObject) {
let playerVC = PlayerViewController()
playerVC.playVideo(urlString)
[self.presentViewController(playerVC, animated: true, completion: nil)]
}
In the PlayerViewController
func playVimeoVideo(link : String) {
player = AVPlayer(URL: NSURL(string: link)!)
player?.play()
}
Notice
The question and some answers may be a little misleading so that you might think that only the url with ".mp4" at the end can be played by the Apple TV. I believed so at the first time I saw the post. It is not true. In fact, with AVPlayerViewController you can play Vimeo streaming video! The link to the stream video is not like https://vimeo.com/92655878. It is possible to get it from Vimeo site by extracting it from a json file, which can be downloaded from this link
let link = "https://vimeo.com/api/oembed.json?url=https%3A//vimeo.com/" + videoId
To be able to get correct url for the video, you need to use the Vimeo Pro user access to get the stream link for a specific video.

Google maps sdk - Map overlays evrything in my storyboard

So i am using xcode 6.2 and i am starting with making apps.
but i have a question: whenever i drag something in my storyboard like a navigation bar the map overlays it, it simply won't show up, please help.
Here is my code
#import "ViewController.h"
#interface ViewController () {
GMSMapView *mapView;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:43.642510 longitude:-79.387038 zoom:12 bearing:0 viewingAngle:0];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView.myLocationEnabled = YES;
self.view = mapView;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(43.642510, -79.387038);
marker.title = #"CN-Tower";
marker.snippet = #"A beautifull tower";
marker.map = mapView;
marker.opacity = 0.7;
}
Thanks anyway,
JP
When you do self.view = mapView you're setting the root view of the view controller to the map - and so the map covers everything, replacing whatever you designed in your storyboard.
What you need to do is add the map as a subview of the root view, eg here's a few ways to do it:
Using the Google Maps SDK in views other than the main view
Google Maps iOS SDK - Add UIView/UIButton over a GMSMapView
Google Maps iOS SDK and storyboards

Load xib file from framework

I'm creating some code which I've sorted into a framework - purely because I want to reuse this code elsewhere (other osx apps - not iOS).
Inside my Resources folder I created a xib file. One level higher in my root I have the corresponding Controller file.
If my client app is using storyboards - how would I go about loading this view? Note I did manage to access properties on the mentioned controller so I did all the hook up etc as described in Apple docs and elsewhere.
Thanks in advance!
You have to put the resources in a *.bundle, not a framework.
Just create a new target that's a bundle.
Then load the nibs with:
NSString *resourceBundlePath = [[NSBundle mainBundle] pathForResource:#"myBundle" ofType:#"bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
// load View Controller from that
UIViewController *vc = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:resourceBundle];
Solution: Here is a sample to load xib to create a view in the framework:
Create a new bundle (eg: MyBundle.bundle) and put your all resources (such as: xib, images, audio files, etc) into the new bundle.
Load xib:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString* path = [resourcePath
stringByAppendingPathComponent:#"MyBundle.bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:path];
if(bundle)
{
self.view = [[bundle loadNibNamed:#"MyXibNameWithoutSuffix" owner:nil options:nil] lastObject];
} else {
self.view = [[[NSBundle mainBundle]
loadNibNamed:#"MyXibNameWithoutSuffix" owner:nil options:nil] lastObject];
}
Load image:
UIImage* image = [UIImage imageNamed:#"MyBundle.bundle/MyImageName"];
if(nil == image) {
image = [UIImage imageNamed:#"MyImageName"];
}
If you're using cocopods, please make sure the s.resources has been
set in .podspec file.
s.resources = "MyBundle.bundle/**/*.{png,jpeg,jpg,storyboard,xib,xcassets,plist}"

Creating a Cocoapod library and [UIImage imageNamed:] returns NULL

I have https://github.com/fulldecent/FDChessBoardView working great and am now starting the project again from scratch with pod lib create in order to make a Podspec.
There is one {'.h','.m'} file and some images. The images are in the file system in the provided Pod/Assets folder. The resources are noted in the podspec file with:
s.resource_bundles = {
'FDChessboardView' => ['Pod/Assets/*']
}
(I have also tried directly adding these files into the Development Pods/FDChessboardView/Resources group inside XCode.)
Inside the library implementation file I need to refer to these images. I have tried:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:#"FDChessboardView" ofType:#"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
NSString *imagePath = [bundle pathForResource:#"aa" ofType:#"png"];
UIImage* image = [UIImage imageWithContentsOfFile:imagePath];
Here the imagePath is set correctly. This file exists and file confirms it is a PNG:
[...]aa.png: PNG image data, 182 x 164, 8-bit/color RGBA, non-interlaced
However the UIImage is NULL.
I have also tried these:
image = [UIImage imageNamed:#"aa"];
UIImage *image = [UIImage imageNamed:#"FDChessboardView.bundle/aa.png"];
image = [UIImage imageNamed:#"aa" inBundle:bundle compatibleWithTraitCollection:nil];
All of them produce NULL.
Could anyone help point me in the correct direction for how to load theme image assets?
Thank you!
Will
Ok - I found a solution that works for me:
In the lib I am creating, I have the following class: AEBubbleField.h AEBubbleView.m
I also have an image in the Assets folder of the generated file structure called background.png. I want to use this in my lib files above so I add the following to the pod spec (to ensure the png is copied with my lib classes)
s.ios.resource_bundle = { 'AEBubbleField' => 'Pod/Assets/*.png' }
I can then access the image in the following manner:
NSBundle *bundle = [NSBundle bundleForClass:[self class]]; // Any class in the lib can be used here, I just went for the current class
UIImage *backgroundImage = [UIImage imageNamed:#"background.png" inBundle:bundle compatibleWithTraitCollection:nil];
This is the only way I can get the image and use it. All other methods I have tried simply return nil like the original question's.
this answer works for me.
https://stackoverflow.com/a/34324540/1897767
and, my swift code is:
class func loadImage(name: String) -> UIImage? {
let podBundle = NSBundle(forClass: MyClass.self)
if let url = podBundle.URLForResource("MyBundleName", withExtension: "bundle") {
let bundle = NSBundle(URL: url)
return UIImage(named: name, inBundle: bundle, compatibleWithTraitCollection: nil)
}
return nil
}
Rob's answer didn't work for me, I think because I didn't change the resource bundle setup from the default in pod lib create
s.resource_bundles = {
'PodCore' => ['Pod/Assets/*.png',
'Pod/Classes/**/*.xib',
'Pod/Classes/**/*.storyboard']
}
I was able to load images from that resource bundle, but had to define it explicitly.
NSString *bundleURL = [[NSBundle mainBundle] pathForResource:#"PodCore"
ofType:#"bundle"];
NSBundle *podBundle = [NSBundle bundleWithPath:bundleURL];
UIImage *image = [UIImage imageNamed:#"home_black.png"
inBundle:podBundle
compatibleWithTraitCollection:nil];
If you're using Swift 2 > you can access this way:
// should access the bundle for this class
let bundle = NSBundle(forClass: self.classForCoder)
// successfully loaded image
let myImageToUse = UIImage(named: "image", inBundle: bundle, compatibleWithTraitCollection: nil)

Resources