I'm creating a UIScrollView that can hold images and videos from different sources. I first created and added a UIView for each image/video to the UIScrollView, then add the image/video view/layer. This works fine for images and videos using AVFoundation; however, does not work for videos using the Youtube API.
Here's my code for adding the YTPlayerView to the UIView within the UIScrollView:
YTPlayerView * youtubePlayerView = [[YTPlayerView alloc] initWithFrame: CGRectMake(0, 0, self.scrollViewWidth, self.scrollViewHeight)];
youtubePlayerView.bounds = CGRectMake(0, 0, self.scrollViewWidth, self.scrollViewHeight);
NSString * youtubePath = [media getMediaPath]; //Valid Youtube URL as NSString
NSMutableString *videoUrlCopy = [NSMutableString stringWithString:youtubePath];
NSString *vID = [videoUrlCopy lastPathComponent];
NSDictionary *playerVars = #{
#"playsinline" : #1
};
youtubePlayerView.delegate = self;
[contentView addSubview:youtubePlayerView]; //ContentView is subview of UIScrollview
[youtubePlayerView loadWithVideoId:vID playerVars:playerVars];
[youtubePlayerView playVideo];
When I try to load the youtube video with loadWithVideoId, the process terminates within YTPlayerView here: UIWebView *webView = [[UIWebView alloc] initWithFrame:self.bounds]; throwing EXC_BAD_ACCESS.
- (UIWebView *)createNewWebView {
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.bounds];
webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
return webView;
}
Interestingly, I've gotten the Youtube videos to show adding the YTPlayerView directly as a subview to self.view. Any suggestions?
I figure it out, using
pod 'youtube-ios-player-helper', :git=>'https://github.com/youtube/youtube-ios-player-helper', :commit=>'head'
instead of using pod 'youtube-ios-player-helper'
Cheers
Related
I want to add a subView to this WKWebView with this content (https://www.windytv.com/?-34.816,138.608,5). so that the subView can be panning along with the webview (imagine there's landmark view being panning along), but I could do it.
I tried many ways as follows:
I add a landmarkView to different subViews of the webView, failed.
1.1 For example:
[self.webView addSubView:landmarkView];
1.2 Or:
[self.webView.scroolView addSubView:landmarkView];
1.3 Or:
[self.webView.scroolView.subViews.firstObject addSubView:landmarkView]; // In viewDidAppear
The interesting thing here is the view hierachy of WKWebsite will change in viewDidAppear. It gets more subView like "WKContentView".
Followed by 1., I try to add a gestureView to pass the gesture to move the landmarkView, failed. The action of the gesture did not procceed.
1.1. For example, I add on the super view of webView.
[self.view addSubView: baseView];
[self.baseView addSubView: webView];
self.panGestureRecognizer.cancelsTouchesInView = NO;
[webView addGestureRecognizer: self.panGestureRecognizer];
Or, I add on the subView of webView.
[self.view addSubView: webView];
[self.webView addSubView: gestureView];
gestureView.backgroundColor = [UIColor clearColor];
self.panGestureRecognizer.cancelsTouchesInView = NO;
[gestureView addGestureRecognizer: self.panGestureRecognizer];
Anyone familiar with WKWebView?
Except for UIGesture, Is there other ways to distribute a touch to many views?
If I could override the touchesBegan method in one of the subViews, it should be much easier. And I think hitTest still work only on a view.
The general
- (void)viewDidLoad
{
UIView *landmarkView = [[UIView alloc] initWithFrame:CGRectMake(200, 200, 200, 200)];
landmarkView.backgroundColor = [UIColor redColor];
NSString *path = #"https://www.windytv.com/?-37.331,145.102,7";
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
[self.view addSubView: self.webView];
[self.webView.scrool addSubView:landmarkView]; // This is one of the failed attempts.
}
It can be solved by adding a panGesture with this delegate method.
The trick is introduced here:
UIPanGestureRecognizer on MKMapView?
Has anyone managed to successfully add a header or footer view to a WKWebView ScrollView?
I'm currently trying to do this using the method described here for a UIWebView Adding a header view to a UIWebView similar to Safari and Articles.
When this method is used in a WKWebView the content view origin.y is correctly changed but content is cut off at the bottom.
Using the scroll view content offset is also not possible as it breaks fixed positioned CSS elements in the web view.
In webView Delegate method
- (void)webViewDidFinishLoad:(UIWebView *)webView
add the following codebase,
mainWebViewObj.scrollView.contentInset = UIEdgeInsetsMake(headerView.frame.size.height,0.0,headerView.frame.size.height,0.0);
mainWebViewObj.scrollView.backgroundColor = [UIColor whiteColor];
if(![headerView superview])
{
[webView.scrollView addSubview:headerView];
[webView.scrollView bringSubviewToFront:headerView];
}
[mainWebViewObj.scrollView setContentOffset:
CGPointMake(0, -mainWebViewObj.scrollView.contentInset.top) animated:NO];
this worked perfect for me. Hope it solves your problem.
Here's an example that I think does as you describe. It offsets the web content by setting contentInset on the scrollView, and by offsetting the header view frame by a negative amount:
#implementation ViewController
{
WKWebView* _webView;
UIView* _headerView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_webView = [[WKWebView alloc] initWithFrame: self.view.bounds];
[self.view addSubview: _webView];
[_webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: #"http://www.stackoverflow.com"]]];
[_webView.scrollView setContentInset: UIEdgeInsetsMake(100, 0, 0, 0)];
_headerView = [[UIView alloc] initWithFrame: CGRectMake(0, -100, 375, 100)];
_headerView.backgroundColor = [UIColor redColor];
[_webView.scrollView addSubview: _headerView];
}
- (void) viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
_webView.frame = self.view.bounds;
CGRect f = _headerView.frame;
f.size.width = _webView.bounds.size.width;
_headerView.frame = f;
}
I've looked at 20+ different posts that are vaguely related to this and haven't been able to find a solution.
What I have is a class which subclasses UIViewController. On this class's loadView method, I'm adding a UIWebView inside of a UIScrollView. The UIWebView has scalesPageToFit set to YES. The problem I'm facing is that it seems like zooms are being multiplied! i.e. When you zoom inside the web view the very first time, everything seems to work properly. When you zoom AGAIN, it seems that it takes your already zoomed version and tries to amplify that by an additional factor. This causes the app to crash. Any thoughts on how to fix this? I think something about the reported zoomScale from the UIWebView is messing things up.
Here's a modified sample code to get an idea of the current implementation:
# This is a UIViewController
#implementation MyViewController
- (void)loadView
{
[super loadView];
self.view.accessibilityLabel = #"MyView";
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.backgroundColor = [UIColor blueColor];
self.scrollView.scrollsToTop = YES;
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.scrollView];
// constraints removed from sample for readability
self.headerView = [[UIViewController alloc] init];
[self.scrollView addSubview:self.headerView];
self.bodyView = [[UIWebView alloc] init];
self.bodyView.delegate = self;
self.bodyView.scalesPageToFit = YES;
self.bodyView.scrollView.scrollsToTop = NO;
self.bodyView.translatesAutoresizingMaskIntoConstraints = NO;
[self.bodyView.scrollView addObserver:self
forKeyPath:KeyValuePath
options:NSKeyValueObservingOptionNew
context:nil];
[self.scrollView addSubview:self.bodyView];
// other constraints here
}
Any help or feedback would be immensely appreciated.
This is my custom view for video player.
Interface File : Movieplayer.h
#import <UIKit/UIKit.h>
#interface MoviePlayer : UIView{
}
#property (strong) UIButton *videoButton;
#end
Implementation File: Movieplayer.m
#import "MoviePlayer.h"
#import <MediaPlayer/MediaPlayer.h>
#implementation MoviePlayer
MPMoviePlayerViewController *movieController;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
_videoButton = [[UIButton alloc] initWithFrame:self.frame];
NSLog(#"My view frame: %#", NSStringFromCGRect(self.frame));
[_videoButton setBackgroundImage:[UIImage imageNamed:#"video-default.jpg"] forState:UIControlStateNormal];
[_videoButton addTarget:self action:#selector(showPlayer:) forControlEvents:UIControlEventTouchUpInside];
int current_tag = rand();
[_videoButton setTag:current_tag];
NSLog(#"Current tag : %d",current_tag);
[self addSubview:_videoButton];
}
return self;
}
-(void) showPlayer : (UIButton *) sender {
NSURL *movieURL = [NSURL URLWithString:#"http://km.support.apple.com/library/APPLE/APPLECARE_ALLGEOS/HT1211/sample_iTunes.mov"];
movieController = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
[movieController.view setFrame:_videoButton.frame];
[movieController.moviePlayer play];
[self addSubview:movieController.view];
}
#end
When i am using this class in viewcontroller, it works fully on the first control. But if i add 2 instance of the same class, the button selector is not fired for the second one.
here is how i am using it,
- (void)viewDidLoad
{
[super viewDidLoad];
UIScrollView *scrolview = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)];
// Do any additional setup after loading the view, typically from a nib.
MoviePlayer *mplayer = [[MoviePlayer alloc] initWithFrame:CGRectMake(0, 0, 320, 180)];
[scrolview addSubview:mplayer];
MoviePlayer *mplayer2 = [[MoviePlayer alloc] initWithFrame:CGRectMake(0, 180, 320, 180)];
[scrolview addSubview:mplayer2];
[self.view addSubview:scrolview];
[scrolview setContentSize:CGSizeMake(320, 600)];
}
When i click on mplayer1, it plays the video, all works here. When i click on mplayer2 nothing happens. in mplayer2, it does not call Showplayer method.
Please help.
Change the frame of the button by below way.
_videoButton = [[UIButton alloc] initWithFrame:CGRectMake(0,0,frame.size.width, frame.size.height)];
For second MoviePlayer view, the frame starts with origin.y = 180. So your button will be placed outside of your view. Change the button frame as above to solve the issue.
The problem you're having is that the _videoButton is not actually inside the bounds of its parent MoviePlayer view. In the init function, you say:
_videoButton = [[UIButton alloc] initWithFrame:self.frame];
Since the _videoButton's frame is relative to its superview, this means for your section MoviePlayer, the _videoButton gets a frame with a y value of 180. This means it is 180 points below the top of the MoviePlayer. The MoviePlayer, though, is only 180 points tall, itself, so the _videoButton is entirely outside of its parent view. This prevents you from tapping on it, even though it's visible. (By default, views don't hide subviews if they are outside of their bounds.) You can verify this by giving your MoviePlayer view a background color.
The fix is easy: don't pass your own frame to any child views. You probably instead want to do something like:
_videoButton = [[UIButton alloc] initWithFrame:self.bounds];
If you want the child view to take up the entire parent view. (Or, even better, use a nib or autolayout constraints to avoid these kinds of issues.)
I'm trying to implement an Adobe Edge animation inside a UIWebView in my IOS7 app. But all I get is a white screen. The same white screen shows up on my iPhone's Safari. The animation runs fine on my laptop's browsers, both Safari and Chrome.
I'm thinking this is an Adobe Edge problem, but here's my IOS code anyway:
NSString *filePathString = [[NSBundle mainBundle] pathForResource:#"YallaBye_Button2" ofType:#"html"];
NSMutableString *html = [[NSMutableString alloc] initWithContentsOfFile:filePathString encoding:NSUTF8StringEncoding error:nil];
NSURL *aURL = [NSURL fileURLWithPath:filePathString];
UIWebView *view = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
view.delegate = self;
[view stringByEvaluatingJavaScriptFromString:#"window.requestAnimationFrame = window.setTimeout;"];
[view loadHTMLString:html baseURL:aURL];
[self.indicatorForPlans addSubview:view];
The indicator works fine without the Adobe Edge html.
I also tried running the [view stringByEvaluatingJavaScriptFromString:#"window.requestAnimationFrame = window.setTimeout;"]; call inside the UIWebViewDelegate method - (void)webViewDidFinishLoad:(UIWebView *)webView but no luck.
Also, researching the forums, I tried changing my transform:translateX(0px); to -webkit-perspective: 1000; -webkit-backface-visibility: hidden; but still just a white screen.
What am I missing?