MPMoviePlayerController not visible in custom UIView - ios

I'm trying to initialise an MPMoviePlayerController in a custom UIView. I do hear the sound but no view. I think something is wrong with initialising the view. I tried it by implementing in the ViewController, then it does work.
Here my code:
import UIKit
import MediaPlayer
class CustomView: UIView {
var sponsor: Sponsors!
var videoContainer = UIView()
var videoPlayer = MPMoviePlayerController()
override init(frame: CGRect) {
super.init(frame: frame)
//Init
layer.cornerRadius = 3.0
backgroundColor = UIColor.whiteColor()
//VideoContainer
videoContainer.backgroundColor = UIColor.blackColor()
//Adding the views
addSubview(videoContainer)
videoContainer.addSubview(videoPlayer.view)
}
//MARK: InitCoder
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
//MARK: AddDataToView
func addDataToView(sponsor: Sponsors) {
//VideoPlayerx
let path = NSBundle.mainBundle().pathForResource("movie5", ofType:"mov")
let url = NSURL.fileURLWithPath(path!)
videoPlayer = MPMoviePlayerController(contentURL: url)
videoPlayer.prepareToPlay()
}
//MARK: LayoutSubViews
override func layoutSubviews() {
super.layoutSubviews()
//VideoContainer
videoContainer.frame = CGRectMake(8, 8, frame.size.width - 16, 219)
//Video
videoPlayer.view.frame = CGRectMake(8, 8, frame.size.width - 16, 219)
videoPlayer.scalingMode = .AspectFill

You need to set frame and add subview after create videoPlayer object. In addDataToView you init videoPlayer again so every settings before that are cleared.

Related

How to correctly handle movement on a zoomed image with a UIScrollView?

I am new to Swift and I'm trying to reproduce the behavior most applications have when you zoom in an image (like Twitter, Facebook etc...). Basically, you tap on the image, it opens fullscreen and then you can zoom in and move freely around the zoomed in image. However, I'm having trouble with the last two parts.
My main ViewController has an instance of a custom UIImageView called TappableImage, which inherits from UIImageView. I use this class as a wrapper to handle touch and transitions, code is below:
import UIKit
class TappableImage: UIImageView {
private let windowBounds: CGRect = UIScreen.main.bounds
private let imageV: UIImageView = UIImageView()
private var startingFrame: CGRect = .zero
private var backdrop: ImageBackdrop!
private var isOpen: Bool = false
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
image = UIImage(named: "kaws") // horizontal
// image = UIImage(named: "portrait") // vertical
// image = UIImage(named: "ksg") // square
isUserInteractionEnabled = true
startingFrame = frame
imageV.image = self.image
imageV.frame = startingFrame
imageV.contentMode = .scaleAspectFill
imageV.isUserInteractionEnabled = true
backdrop = ImageBackdrop(frame: windowBounds, with: imageV)
let openTapGesture = UITapGestureRecognizer(target: self, action: #selector(onTap))
openTapGesture.numberOfTapsRequired = 1
addGestureRecognizer(openTapGesture)
}
#objc private func onTap(_ sender: UITapGestureRecognizer) {
guard let window = UIApplication.shared.windows.first else {
print("no window...")
return
}
window.addSubview(backdrop)
UIView.animate(withDuration: 0.25, animations: {
self.backdrop.alpha = 1
let h = (self.windowBounds.width / self.startingFrame.width) * self.startingFrame.height
let y = self.windowBounds.height / 2 - h / 2
self.imageV.frame = CGRect(x: 0, y: y, width: self.windowBounds.width, height: h)
}) { (_) in
self.isOpen = true
}
}
}
When a user tap the image, I bring a custom UIScrollView to the front in which I added my TappableImage. The UIScrollView is a basic implementation just handling pinching, code is below:
import UIKit
class ImageBackdrop: UIScrollView, UIScrollViewDelegate {
private var imageView: UIImageView!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
convenience init(frame: CGRect, with imgv: UIImageView) {
self.init(frame: frame)
imageView = imgv
setupScrollView()
addSubview(imageView)
}
private func setupScrollView() -> Void {
delegate = self
backgroundColor = .black
alpha = 0
minimumZoomScale = 1.0
maximumZoomScale = 5.0
contentSize = imageView.bounds.size
autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? { imageView }
}
My issue is that when I zoom in, the image is shifted down and I cannot move freely around with one finger. If I try to move to the bottom of the image, I am "slingshotted" back to the top, like when you arrive at the end of a list, you can find a video of this behavior here.
My guess is that the UIImageView center or size is incorrect but I cannot find a way to fix it.

custom UISlider subview frame is offset from main view

my custom uislider background uiview is offset from original view frame.
and the further the the slider original (x,y) from 0,0 the more the offset.
Please check the image below.
uislider subview frame offset
import UIKit
class customSlier: UISlider {
override func awakeFromNib() {
super.awakeFromNib()
self.initializeSomeSettings()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func initializeSomeSettings() {
let view: UIView = UIView()
view.frame = self.frame
view.backgroundColor = UIColor.yellow
self.insertSubview(view, belowSubview: self)
}
override func layoutSubviews() {
super.layoutSubviews()
}
}
I think the problem is at this line:
view.frame = self.frame
Let's say your scroller is at position (10, 10). Then the background frame is also at position (10,10) in the coordinator of the scroll frame, which is (20,20) in the original view. My suggestion is to replace this line by this:
view.frame = CGRect(origin: .zero, size: self.frame.size)
Hope this helps.
try this
view.frame = self.bounds

Not able to show border color and background as blur in custom view as popup view in Swift

I have some requirement to show popup as some customisation options.
So, I took custom view as UIView with Xib file.
class CustomAlertView : UIView {
#IBOutlet weak var customAlertView : UIView!
#IBOutlet weak var button1 : UIButton!
#IBOutlet weak var button2 : UIButton!
override init(frame: CGRect) { // for using CustomView in code
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) { // for using CustomView in IB
super.init(coder: aDecoder)
self.commonInit()
}
private func commonInit() {
Bundle.main.loadNibNamed("CustomAlertView", owner: self)
guard let content = customAlertView else { return }
content.frame = self.bounds
content.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.addSubview(content)
}
}
And given outlet connections.
And I am able to load the view in viewcontroller class.
But, the issue is, its not showing as pop up view and its not showing any border color, etc even I added too.
And the present self.view (Main view from viewcontroller) still moving it has tableview, while I clicking on the buttons on custom view, nothing happening.
func someAction() {
self.view.addSubview(customAlert)
self.customAlert.layer.cornerRadius = 13
self.customAlert.layer.borderWidth = 10
self.customAlert.layer.borderColor = UIColor.gray.cgColor
self.customAlert.clipsToBounds = false
let radius: CGFloat = self.customAlert.frame.width / 2.0 //change it to .height if you need spread for height
let shadowPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 2.1 * radius, height: self.customAlert.frame.height))
self.customAlert.layer.masksToBounds = false
self.customAlert.layer.cornerRadius = 8; // if you like rounded corners
self.customAlert.layer.shadowOffset = CGSize(width:-15, height:20);
self.customAlert.layer.shadowRadius = 5;
self.customAlert.layer.shadowOpacity = 0.5;
self.customAlert.layer.shadowPath = shadowPath.cgPath
self.customAlert.byMonthlyBtn.addTarget(self, action: #selector(button1tapped), for: .touchUpInside)
self.customAlert.byAnnuallyBtn.addTarget(self, action: #selector(button2tapped), for: .touchUpInside)
}
And its looks like below screenshot
Any suggestions?
private func commonInit() {
Bundle.main.loadNibNamed("CustomAlertView", owner: self)
guard let content = customAlertView else { return }
content.frame = self.bounds
content.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.addSubview(content)
}
Your problem is you are using the CustomAlertView you loaded. Try adjust your code like below.
private func commonInit() {
guard let view = Bundle.main.loadNibNamed("CustomAlertView", owner: self)?.first as? CustomAlertView else {
return
}
view.frame = bounds
view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
addSubview(view)
}

how to pass parameter in init method of UIView?

Let me know if i have made any mistake don't downcast the question.
here is the problem i am trying to play a video and following is code
import UIKit
import AVFoundation
// custom UIView to display frame for avplayer
class VideoPlayerView: UIView {
let urlString String?
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .blackColor()
//static url for video
urlString = "https://firebasestorage.googleapis.com/v0/b/gameofchats-762ca.appspot.com/o/message_movies%2F12323439-9729-4941-BA07-2BAE970967C7.mov?alt=media&token=3e37a093-3bc8-410f-84d3-38332af9c726"
if let url = NSURL(string: urlString) {
let player = AVPlayer(URL: url)
let playerLayer = AVPlayerLayer(player: player)
self.layer.addSublayer(playerLayer)
playerLayer.frame = self.frame
player.play()
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// view controller to launch video player
class VideoPlayerController: UIViewController {
var message: Messages?{
didSet{
}
}
let overlayView: UIView = {
let view = UIView()
view.isUserInteractionEnabled = true
view.backgroundColor = UIColor(white: 0, alpha: 0.5)
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
let height = view.frame.width * 9 / 16
let videoPlayerFrame = CGRect(x: 0, y: 0, width: view.frame.width, height: height)
let videoPlayerView = VideoContainerView(frame: videoPlayerFrame)
view.addSubview(videoPlayerView)
videoPlayerView.center = view.center
}
in the init method of VideoPlayerView i have used static url of video for urlString property which is playing fine. i want to set urlString property from my videoPlayerController class how i can do that ? because when i initialize
let view = VideoPlayerView(frame:frame) // this code will call init method before i can set the urlString property.
anyone have idea how to do that. please help. thank you in advance for any suggestions.
Just make other initializer with needed parameters and call it.
convenience init(frame: CGRect, urlString: String) {
self.init(frame: frame)
//make here what you want
}

Adding Blur effect to view

I have a view class which is used for showing a spinner with a blurred background view. I add this to another view during runtime and everything works fine. When I add this view to another ViewControllers view somehow the effect is not visible.The view does get added, I check it by setting the background colour to green and it is there.But the effect itself is not visible.I add the view in this manner
Ex:
self.view.addSubview(self.loadingView)
self.loadingView.frame = CGRect(origin: .zero, size:self.view.frame.size)
.The Implementation is as below,
final class LoaderView: UIView {
fileprivate let spinner = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
fileprivate let effect = UIBlurEffect(style: .light)
fileprivate let backgroundView = UIVisualEffectView(frame:.zero)
override init(frame: CGRect) {
spinner.startAnimating()
super.init(frame: frame)
backgroundView.effect = effect
addSubview(backgroundView)
addSubview(spinner)
}
#available(*, unavailable)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setSpinnerColor(color:UIColor){
spinner.color = color
}
override func layoutSubviews() {
super.layoutSubviews()
backgroundView.frame = CGRect(x: 0, y: 0, width: self.bounds.height/5, height: self.bounds.height/5)
backgroundView.center = CGPoint(x:self.bounds.size.width / 2.0, y: self.bounds.size.height / 2.0)
backgroundView.clipsToBounds = true
backgroundView.cornerRadius = 10
spinner.center = center
}
}

Resources