# What should i know somethings about making custom ui through uikit in iOS?

**URL:** <https://community.bitmovin.com/t/what-should-i-know-somethings-about-making-custom-ui-through-uikit-in-ios/2116>\
**Category:** Support\
**Tags:** ios\
**Created:** [July 7, 2023, 1:28am UTC](https://community.bitmovin.com/t/what-should-i-know-somethings-about-making-custom-ui-through-uikit-in-ios/2116 "2023-07-07T01:28:02Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![pdhou23](https://avatars.discourse-cdn.com/v4/letter/p/ecccb3/32.png) [@pdhou23](https://community.bitmovin.com/u/pdhou23)\
**Post date:** [July 7, 2023, 1:28am UTC](https://community.bitmovin.com/t/what-should-i-know-somethings-about-making-custom-ui-through-uikit-in-ios/2116/1 "2023-07-07T01:28:02Z")

</div>

I asked that related to making custom ui through uikit in iOS 2 days ago.

So, i maked custom ui through the way you taught me.

And then, I’m curious about somthings in that process.

1. if i wanna use custom ui, can’t i use method already existed in player reference? and should i make needed function and event handler(ex. delegate pattern, notificaton, etc.) that like making custom ui?

When I make custom View like the part of player reference below

[https://cdn.bitmovin.com/player/ios/3/docs/Classes/PlayerView.html](https://cdn.bitmovin.com/player/ios/3/docs/Classes/PlayerView.html)

i wanna use methods that already existed in player reference but, picture in picture mode don’t operate.

so, i added a apple’s AVPictureInPictureController type’s instance property and i have been using picture in picture mode.

Like this case if i wanna use custom ui, i can’t use method already existed in player reference? and should i make needed function that like making custom ui? or is there other solution?

```auto
class TESTPlayerView: UIView {
    override class var layerClass: AnyClass {
        AVPlayerLayer.self
    }
    var player: Player? = nil
    
    var playerLayer: AVPlayerLayer {
        layer as! AVPlayerLayer
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        print("test- view initialized")
    }
    
    init(player: Player, frame: CGRect) {
        super.init(frame: frame)
        self.player = player
// let subLayer = CALayer()
// subLayer.frame = CGRect(x: 10, y: 10, width: 100, height: 100)
// subLayer.backgroundColor = UIColor.yellow.cgColor
//
// let subLayer2 = CALayer()
// subLayer2.frame = CGRect(x: 120, y: 10, width: 100, height: 100)
// subLayer2.backgroundColor = UIColor.blue.cgColor
//
// let subLayer3 = CALayer()
// subLayer3.frame = CGRect(x: 230, y: 10, width: 100, height: 100)
// subLayer3.backgroundColor = UIColor.systemPink.cgColor
//
// playerLayer.addSublayer(subLayer)
// playerLayer.addSublayer(subLayer2)
// playerLayer.addSublayer(subLayer3)
        
        let view1 = UIButton(frame: CGRect(x: 10, y: 10, width: 100, height: 50))
        view1.addTarget(self, action: #selector(didTapTouch), for: .touchUpInside)
        view1.backgroundColor = .systemBlue
        
// let view2 = UIView(frame: CGRect(x: 120, y: 10, width: 100, height: 100))
        let view2 = UIButton(frame: CGRect(x: 120, y: 10, width: 100, height: 50))
        view2.addTarget(self, action: #selector(didTapTouch2), for: .touchUpInside)
        view2.backgroundColor = .systemYellow
        
// let view3 = UIView(frame: CGRect(x: 230, y: 10, width: 100, height: 100))
        let view3 = UIButton(frame: CGRect(x: 230, y: 10, width: 100, height: 50))
        view3.addTarget(self, action: #selector(didTapTouch3), for: .touchUpInside)
        view3.backgroundColor = .systemPink
        
        self.addSubview(view1)
        self.addSubview(view2)
        self.addSubview(view3)
        
        self.player?.register(playerLayer)
    }
    
    @objc func didTapTouch() {
        player?.play()
    }
    
    @objc func didTapTouch2() {
        player?.pause()
    }
    
    @objc func didTapTouch3() {
        
    }
}

```

```auto
final class ViewController: UIViewController {
    var player: Player!
    var pictureInPictureController: AVPictureInPictureController?
    ...
    playerConfig.playbackConfig.isBackgroundPlaybackEnabled = true
    playerConfig.playbackConfig.isPictureInPictureEnabled = true
    player = PlayerFactory.create(playerConfig: config)
    
      let testPlayerView = TESTPlayerView(player: player, frame: .zero)
        
        self.pictureInPictureController = AVPictureInPictureController(playerLayer: testPlayerView.playerLayer)
        self.pictureInPictureController?.delegate = self

        player.add(listener: self)
        
// playerView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        testPlayerView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height / 2)
        view.addSubview(testPlayerView)
        view.bringSubviewToFront(testPlayerView)
// playerView.backgroundColor = .lightGray

        configureAudioSession()
        
        let sourceConfig = SourceConfig(url: streamUrl, type: .hls)
        player.load(sourceConfig: sourceConfig)
        
    }
    
    private func configureAudioSession() {
        let audioSession = AVAudioSession.sharedInstance()
        try? audioSession.setCategory(.playback)
    }

```

1. How can i player view’s add(listener:) method in custom player view?  
Should i conform to what protocol and then typing concrete code?

2. I wanna know somethings that conform to what protocols and where i typing concrete codes each code, when i wanna use to custom player view.

---

<div class="post-metadata">

**Author:** ![davidsteinacher](https://sea1.discourse-cdn.com/flex015/user_avatar/community.bitmovin.com/davidsteinacher/32/163_2.png) [@davidsteinacher](https://community.bitmovin.com/u/davidsteinacher)\
**Post date:** [July 9, 2023, 10:39am UTC](https://community.bitmovin.com/t/what-should-i-know-somethings-about-making-custom-ui-through-uikit-in-ios/2116/2 "2023-07-09T10:39:32Z")

</div>

Hi @pdhou23,

It looks like the other post was pointing you into the wrong direction as it mentions the system UI and not a custom UIKit UI.

However, you are already on the right track with what I can see from your post.

1. When creating a custom UI you need to take care of PiP on your own. This can be achieved with the `AVPictureInPictureController` as you seem to already doing it. You can then use [`startPictureInPicture`](https://developer.apple.com/documentation/avkit/avpictureinpicturecontroller/1614687-startpictureinpicture) and [`stopPictureInPicture`](https://developer.apple.com/documentation/avkit/avpictureinpicturecontroller/1614701-stoppictureinpicture) to control the state.
2. To receive events from the `Player` you can either use the listener (delegate) approach using the [`PlayerListener`](https://cdn.bitmovin.com/player/ios/3/docs/Protocols/PlayerListener.html) or through our new modern approach using the [`PlayerEventsApi`](https://cdn.bitmovin.com/player/ios/3/docs/Classes/PlayerEventsApi.html).
3. There are no additional protocol implementations needed when creating a custom UI.

Hope that helps. If you have any additional questions feel free to reply to this thread.
