I have a YouTubePlayer (from here) in my app. I have a UIViewController (we'll call this MainViewController) with a UITableView full of videos. Whenever a user taps on a cell, it opens another UIViewController (we'll call this DetailViewController) with my custom xib view called playerView. Like I said, playerView is a custom xib view and in that view is my YouTubePlayer. This is how I set up playerView in my DetailViewController
playerContainer.addSubview(playerView)
playerView.frame = CGRect(x: 0, y: 0, width: playerContainer.frame.size.width , height: playerContainer.frame.size.height)
playerView.player.loadVideoID(nowPlayingVideo.id)
Ok so this works great. BUT... whenever the user dismisses DetailViewController, I want playerView to be moved to the MainViewController. Like where the user can see what is playing in the background. So to do this, I added this code in DetailViewController...
override func viewWillDisappear(_ animated: Bool) {
nowPlayingView.addSubview(playerView)
playerView.frame = CGRect(x: 8, y: 8, width: width, height: height)
playerView.layoutIfNeeded()
}
nowPlayingView is another custom xib view and is added to the app's window earlier on. So this is where I start running into problems. This code works great. The frame is changed correctly and it's added to nowPlayingView, but, the YouTubePlayer in playerView seems to reload. So it pauses playback, shows a loading icon, and then resumes. It's pretty annoying. This shouldn't be happening because the video is already loaded in the YouTubePlayer. I'm pretty sure it happens only whenver I am changing the frame of playerView. Does anyone have any ideas on how to fix this?
When the video resumes playing after loading, does the video start over or does it resume where it left off before changing the view?
Related
I have a view class with xib file so I want to use this view at the background of the button so I used subview but the problem is that the subview of the button will be inFront of the button so I can't click button any more I used UI Debugging mode and I realized that the button is at the back of the view so I used send to back in my codes But still the view is inFront of the Button !
let adsView = videoAdsView()
func adsOutlet() {
self.adsView.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
self.showAdsOutlet.addSubview(adsView)
self.showAdsOutlet.sendSubview(toBack: self.adsView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
adsOutlet()
}
put following code at the end of adsOutlet method:
self.adsView.isUserInteractionEnabled = false
If you want to add your button as a subview of your background view then you can just do that, and your button will be in front of the background:
self.backgroundView.addSubview(adsButton)
If you don't want adsButton as a subview of the backgroundView but you want to make sure it's presented in front of the backgroundView then assuming that both are subview's of the parent view do this:
self.view.sendSubview(toFront:adsButton)
Please try this code:
Make the button background color clear.
Then write this code:
self.view.bringSubview(toFront: showAdsOutlet)
It may helps to you. Thank you
When loading data from server, we mask our UI using a UIView like the following sample code:
let loadingView = UIView()
loadingView.tag = 9999
loadingView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
loadingView.backgroundColor = UIColor.white.withAlphaComponent(0.4);
controller.view.addSubview(loadingView)
As you can see this loadingView takes the entire width and height of the controller and practically masks the screen. Having alpha means underlying content is translucently visible. We remove this view from controller after data has loaded like this:
for view in controller.view.subviews
{
if view.tag == 9999
{
view.removeFromSuperview()
}
}
However we are seeing strange issue where-in if a user keeps tapping a UIButton on the controller while the loadingView is shown, tap on the button is invoked as many times after the loadingView has been removed from the controller. In other words, our action for UIButton tap gets invoked as many times as you tapped it while the loadingView was shown.
Are we doing something wrong? How can we prevent the tap on UIButton from being invoked while the loadingView is shown?
You should doable user interaction on the loading view.
loadingViee.userInteractionEnabled = false
As you said the loading view is on all over the screen.
You can Ignore touch of your screen during the loading view Once finished loading view you can continue Interaction as like below.
UIApplication.shared.beginIgnoringInteractionEvents()
UIApplication.shared.endIgnoringInteractionEvents()
I have an AVPlayer that's inside collectionview cell, that's inside a UICollectionView, that's located inside a collectionview cell.
I wanted to animate the AVPlayers frame to fit the entire screen, essentially a full screen transition however because of the hierarchy I'm having trouble accessing the main collectionview keywindow...
This is the code I am using so far in an attempt to access the full screens bounds.
let window = UIApplication.shared.keyWindow!
let v = UIView(frame: CGRect(x: -(window.frame.origin.x), y: (window.frame.origin.y) / 2, width: (window.frame.width) / 2, height: (window.frame.height) / 2 ))
UIView.animate(withDuration: 1, delay: 0, options: UIViewAnimationOptions.curveEaseOut, animations: {
self.playerView?.bounds = v.bounds
self.layoutIfNeeded()
}, completion: { (completed) in
})
What this currently does is mask playerView to the bounds of the nested collectionView in the cell. Which leads me to believe because of how the hierarchy is that method might not be feasible.
I was hoping that there would be some method like AVPlayer.fullscreen() or something because I know it is possible to get fullscreen video using AVPlayerControllers overlay view but I don't want the user to have to press a button to go fullscreen. I prefer my current method of just tapping the video.
Any suggesetions?
You need to use an AVPlayerLayer this layer is the one that is going to be added as a sublayer to the view you want.
In this case first you need to add a UIView to your collectionViewCell and add your AVPlayerLayer instance as a sublayer.
When the user tap on the cell you must first remove AVPlayerLayer from the cell and pass the reference to your Root view controller in there you can add a new UIView of the size of the entire screen and add the AVPlayerLayer as a sublayer of that view.
Keep in mind that if you have a navigation controller you should add that UIView as a subview of the navigation controller and if you have a tabBar you need to add it to the tabBar insted.
To return from "Full screen" mode you do the oposite.
I've tried in my code to preload an UIWebView but without any result.
I can't figure out what is wrong in the code.
First UIViewController
func viewDidLoad(){
let gallery = storyboard?.instantiateViewControllerWithIdentifier("Gallery") as! GalleryViewController
gallery.loadwWebView()
}
In the second UIViewController
func loadwWebView(){
let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height: view.bounds.size.height))
webView.loadRequest(NSURLRequest(URL: NSURL(string: "https://www.google.com")!))
self.view.addSubview(webView)
}
I've choose the programmatically to create the UIWebView way because if I use the #IBOutlet its gonna crash.
The problem is that you're instantiating a gallery, which is in turn creating a web view, but gallery is a local variable and will be deallocated when it falls out of scope.
You need to keep a reference to this view controller (e.g. make it a property of the current view controller). If you do this, you need to make sure that when you transition to this view controller, you don't use a segue (because that will create a second instance of that second view controller), but rather programmatically transition to the one you already instantiated.
You might also want to save a reference to that web view you added to the second view controller's view hierarchy because otherwise you won't be able to reference it again (or at least not without some cumbersome enumeration of the subviews).
I have an animation function that works perfectly fine when there is only a single View Controller. When it runs, the block on the left hand side moves to the right hand side. The code for the animation is below.
let timerSquare = UIView()
func timerRectangle(){
timerSquare.backgroundColor = UIColor.greenColor()
timerSquare.frame = CGRect(x: 0, y: 450, width: 50, height: 20)
self.view.addSubview(timerSquare)
UIView.animateWithDuration(2.0, animations:
{
self.timerSquare.backgroundColor = UIColor.redColor()
self.timerSquare.frame = CGRect(x: 270, y: 450, width: 50, height: 20)
}, completition: nil)
}
However the problem happens when I create a view controller with a simple button that segues into the view controller with the animation code. Once it segues into the code the animation doesnt run and it displays the block in its finish position as though the animation had already completed running.
The View controller has no other code other than the animation code and Ive placed the animation function in numerous parts of the view controller including the "ViewDidLoad" section and Im unsure why it doesnt run the animation from the initial position. It works perfectly fine on its own and the only thing different is creating a button seguing into the code so its puzzling me. Any help would be appreciated thanks
I managed to find a solution to the problem. I needed to add the subview in viewDidLoad and then start the animation in viewDidAppear so it would begin as soon as the View appeared. Hope this helped anyone else out there having the same problem