Call Kit
  • iOS : Swift
  • Android
  • Web
  • Flutter
  • React Native
  • Overview
  • Quick start
  • Custom prebuilt UI

Custom prebuilt UI

Last updated:2022-09-26 10:50

Call Kit (ZegoUIKitPrebuiltCall) provides a set of default behaviors and styles. If those don't fully meet your design or business needs, we allow you to flexibly customize the behavior and styles through configuration, as well as add components with custom business logic.

After getting started quickly, you'll know that when you create the ZegoUIKitPrebuiltCall, in addition to the required authentication parameter, there is also a ZegoUIKitPrebuiltCallConfig, which is used for custom configuration.

In this doc, we will describe these parameters in detail to help you do further customization.

Customize prebuilt UI components

Configure layouts

Call Kit (ZegoUIKitPrebuiltCall) currently supports picture-in-picture layout and gallery layout, each layout has its own configurations. To select and configure the layout you want, use the layout parameter in the ZegoUIKitPrebuiltCallConfig:

Picture-in-picture layout

The configurations supported by the picture-in-picture layout are:

  1. showMyViewWithVideoOnly: Whether to display my view when my camera is turned off, displayed by default.
  2. isSmallViewDraggable: Whether the position of the small view in the picture-in-picture layout can be changed by dragging. It’s allowed by default.
  3. switchLargeOrSmallViewByClick: Whether to allow users to click on the small view for switching between large view and small view. It’s allowed by default.

The effect is as follows:

Display my view when my camera is off Hide my view when my camera is off Dragging Switching

Here is the reference code:

class ViewController: UIViewController {

    let selfUserID: String = "userID"
    let selfUserName: String = "userName"
    let yourAppID: UInt32 = YourAppID 
    let yourAppSign: String = YourAppSign
    let callID: String = "testCallID"

    @IBOutlet weak var userIDLabel: UILabel! {
        didSet {
            userIDLabel.text = selfUserID
        }
    }
    @IBOutlet weak var userNameLabel: UILabel! {
        didSet {
            selfUserName = String(format: "zego_%@", selfUserID)
            userNameLabel.text = selfUserName
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func makeNewCall(_ sender: Any) {

        // Modify your custom configurations here.
        let config: ZegoUIKitPrebuiltCallConfig = ZegoUIKitPrebuiltCallConfig(.oneOnOneVideoCall)

        let layout: ZegoLayout = ZegoLayout()
        layout.mode = .pictureInPicture
        let pipConfig: ZegoLayoutPictureInPictureConfig = ZegoLayoutPictureInPictureConfig()
        pipConfig.showMyViewWithVideoOnly = false;
        pipConfig.isSmallViewDraggable = true;
        pipConfig.switchLargeOrSmallViewByClick = true;
        layout.config = pipConfig
        config.layout = layout

        let callVC = ZegoUIKitPrebuiltCallVC.init(yourAppID, appSign: yourAppSign, userID: selfUserID, userName: selfUserName ?? "", callID: callID, config: config)
        callVC.modalPresentationStyle = .fullScreen
        self.present(callVC, animated: true, completion: nil)
    }
}

The configuration supported by the gallery layout is:

addBorderRadiusAndSpacingBetweenView: In gallery layout, this can be used to add border radius and spacing between speaker views. true: enabled (by default). false: disabled.

The effect is as follows:

Adding border radius and spacing Without border radius and spacing
class ViewController: UIViewController {

    let selfUserID: String = "userID"
    let selfUserName: String = "userName"
    let yourAppID: UInt32 = YourAppID
    let yourAppSign: String = YourAppSign
    let callID: String = "testCallID"

    @IBOutlet weak var userIDLabel: UILabel! {
        didSet {
            userIDLabel.text = selfUserID
        }
    }
    @IBOutlet weak var userNameLabel: UILabel! {
        didSet {
            selfUserName = String(format: "zego_%@", selfUserID)
            userNameLabel.text = selfUserName
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func makeNewCall(_ sender: Any) {

        // Modify your custom configurations here.
        let config: ZegoUIKitPrebuiltCallConfig = ZegoUIKitPrebuiltCallConfig(.groupVideoCall)

        let layout: ZegoLayout = ZegoLayout()
        layout.mode = .gallery
        let layoutConfig: ZegoLayoutGalleryConfig = ZegoLayoutGalleryConfig()
        layoutConfig.addBorderRadiusAndSpacingBetweenView = false;
        layout.config = layoutConfig
        config.layout = layout

        let callVC = ZegoUIKitPrebuiltCallVC.init(yourAppID, appSign: yourAppSign, userID: selfUserID, userName: selfUserName ?? "", callID: callID, config: config)
        callVC.modalPresentationStyle = .fullScreen
        self.present(callVC, animated: true, completion: nil)
    }
}

Hide the prebuilt components

By default, the Call Kit (ZegoUIKitPrebuiltCall) displays UserNameLabel, MicrophoneStateIcon, and CameraStateIcon floating above the view. If these components are not needed, you can hide them using the following three configurations in audioVideoViewConfig.

Config Effects
1. showMicrophoneStateOnView: whether to display the microphone state on the view. Displayed by default.
2. showCameraStateOnView: Whether to display the camera state on the view. Displayed by default.
3. showUserNameOnView: Indicates whether to display the username on the view. Displayed by default.
/Pics/ZegoUIKit/Flutter/_normal_switch_30_label.png

Hide sound waves

As shown in the rendering, the Call Kit (ZegoUIKitPrebuiltCall) displays the user's avatar and sound waves when the camera is turned off. If you are not satisfied with the user avatars and sound wave style, you can hide them using the showSoundWavesInAudioMode configurations in audioVideoViewConfig.

  • audioVideoViewConfig: in audio mode, whether to display the sound waves around the user avatar in audio mode. Displayed by default.

Customize the initial device state

When starting a call, the Call Kit (ZegoUIKitPrebuiltCall) turns on the camera, and microphone, and uses the speaker as the audio output device by default.

To change this default configuration, for example, turn off the camera when you start a call, or don't use the speaker (If the speaker is not used, the system's default audio output device, such as ear speaker, headset, Bluetooth, etc., will be used.), you can modify the following configurations:

  1. turnOnCameraWhenJoining: Whether to turn on the camera when the call starts. true: turn on (by default). false: turn off.
  2. turnOnMicrophoneWhenJoining: Whether to turn on the camera when the call starts. true: turn on (by default). false: turn off.
  3. useSpeakerWhenJoining: Whether to use the speaker when the call starts. true: use the speaker (by default). false: use the system's default audio output device, such as an ear speaker, headset, Bluetooth, etc.

Here is the reference code:

class ViewController: UIViewController {

    let selfUserID: String = "userID"
    let selfUserName: String = "userName"
    let yourAppID: UInt32 = YourAppID 
    let yourAppSign: String = YourAppSign
    let callID: String = "testCallID"

    @IBOutlet weak var userIDLabel: UILabel! {
        didSet {
            userIDLabel.text = selfUserID
        }
    }
    @IBOutlet weak var userNameLabel: UILabel! {
        didSet {
            selfUserName = String(format: "zego_%@", selfUserID)
            userNameLabel.text = selfUserName
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func makeNewCall(_ sender: Any) {

        // Modify your custom configurations here.
        let config: ZegoUIKitPrebuiltCallConfig = ZegoUIKitPrebuiltCallConfig(.oneOnOneVideoCall)

        config.turnOnCameraWhenJoining = false;
        config.turnOnMicrophoneWhenJoining = false;
        config.useSpeakerWhenJoining = true;

        let callVC = ZegoUIKitPrebuiltCallVC.init(yourAppID, appSign: yourAppSign, userID: selfUserID, userName: selfUserName ?? "", callID: callID, config: config)
        callVC.modalPresentationStyle = .fullScreen
        self.present(callVC, animated: true, completion: nil)
    }
}

Customize the menu bar button list

Call Kit (ZegoUIKitPrebuiltCall) allows you to configure the buttons of the menu bar. To remove the default buttons or add custom ones to the bottom menu bar, you can configure the bottomMenuBarConfig:

(Similarly, to configure top menu bar buttons or add custom buttons to the top menu bar, use the topMenuBarConfig.)

  1. buttons: Built-in buttons placed in the menu bar. By default, all buttons are displayed. If you need to hide some buttons, use this to configure them.
  2. maxCount: Maximum number of buttons that can be displayed by the menu bar. Value range [1 - 5], the default value is 5.
  3. extendButtons: Use this configuration to add your own custom buttons to menu bar.

If the total number of built-in buttons and custom buttons does not exceed 5, all buttons will be displayed. Otherwise, other buttons that cannot be displayed will be hidden in the three dots (⋮) button. Clicking this button will pop up the bottom sheet to display the remaining buttons.

The effect will be like this:

/Pics/ZegoUIKit/Flutter/menuBarLimit.gif

Customize the hidden behavior of the menu bar

The Call Kit (ZegoUIKitPrebuiltCall) supports automatic or manual hiding of the menu bar. You can control this by using the following two configurations in the ZegoBottomMenuBarConfig:

  1. hideByClick: Whether the menu bar can be hidden by clicking on the unresponsive area, enabled by default.
  2. hideAutomatically: Whether the menu bar is automatically hidden after 5 seconds of user inactivity, enabled by default.

Set a hangup confirmation dialog

Call Kit (ZegoUIKitPrebuilt) ends a call by default when the user clicks the End Call button or the Android’s Back button.

If you want to add a confirmation dialog box to double confirm whether the user wants to hang up a call, you can use the hangUpConfirmInfo config: After configuring the hangUpConfirmInfo parameter, ZegoUIKitPrebuilt will pop up a confirmation dialog box with the default style before ending the call, showing the confirmation info you set.

The effect will be like this:

/Pics/ZegoUIKit/Flutter/hangup_confirm.gif

Here is the reference code:

class ViewController: UIViewController {

    let selfUserID: String = "userID"
    let selfUserName: String = "userName"
    let yourAppID: UInt32 = YourAppID 
    let yourAppSign: String = YourAppSign
    let callID: String = "testCallID"

    @IBOutlet weak var userIDLabel: UILabel! {
        didSet {
            userIDLabel.text = selfUserID
        }
    }
    @IBOutlet weak var userNameLabel: UILabel! {
        didSet {
            selfUserName = String(format: "zego_%@", selfUserID)
            userNameLabel.text = selfUserName
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func makeNewCall(_ sender: Any) {

        // Modify your custom configurations here.
        let config: ZegoUIKitPrebuiltCallConfig = ZegoUIKitPrebuiltCallConfig(.oneOnOneVideoCall)

        let hangUpConfirmDialogInfo = ZegoLeaveConfirmDialogInfo()
        hangUpConfirmDialogInfo.title = "hangup confirm"
        hangUpConfirmDialogInfo.message = "do you want to hangup?"
        hangUpConfirmDialogInfo.cancelButtonName = "cancel"
        hangUpConfirmDialogInfo.confirmButtonName = "confirm"
        config.hangUpConfirmDialogInfo = hangUpConfirmDialogInfo

        let callVC = ZegoUIKitPrebuiltCallVC.init(yourAppID, appSign: yourAppSign, userID: selfUserID, userName: selfUserName ?? "", callID: callID, config: config)
        callVC.modalPresentationStyle = .fullScreen
        self.present(callVC, animated: true, completion: nil)
    }
}

If you want to listen for hang-up events, for example, to save the call recording when ending the call, ZegoUIKitPrebuiltCall provides a setOnHangUpListener method, and the HangUpListener will be triggered when the call ends. And sure, you can also implement custom business logic in the HangUpListener.

Customize the view in audio mode

If you need to customize the user's view in audio mode, for example, setting the background image, you can use largeViewBackgroundImage, smallViewBackgroundImage, largeViewBackgroundColor, smallViewBackgroundColor in ZegoLayoutPictureInPictureConfig.

These configurations are only valid when the user turns off the camera (because the video view will be displayed automatically when the camera is on).

Here is the reference code:

class ViewController: UIViewController {

    let selfUserID: String = "userID"
    let selfUserName: String = "userName"
    let yourAppID: UInt32 = YourAppID 
    let yourAppSign: String = YourAppSign
    let callID: String = "testCallID"

    @IBOutlet weak var userIDLabel: UILabel! {
        didSet {
            userIDLabel.text = selfUserID
        }
    }
    @IBOutlet weak var userNameLabel: UILabel! {
        didSet {
            selfUserName = String(format: "zego_%@", selfUserID)
            userNameLabel.text = selfUserName
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func makeNewCall(_ sender: Any) {

        // Modify your custom configurations here.
        let config: ZegoUIKitPrebuiltCallConfig = ZegoUIKitPrebuiltCallConfig(.oneOnOneVideoCall)

        let layout: ZegoLayout = ZegoLayout()
        layout.mode = .pictureInPicture
        let pipConfig: ZegoLayoutPictureInPictureConfig = ZegoLayoutPictureInPictureConfig()
        pipConfig.largeViewBackgroundColor = UIColor.darkGray
        pipConfig.smallViewBackgroundColor = UIColor.lightGray
        layout.config = pipConfig
        config.layout = layout

        let callVC = ZegoUIKitPrebuiltCallVC.init(yourAppID, appSign: yourAppSign, userID: selfUserID, userName: selfUserName ?? "", callID: callID, config: config)
        callVC.modalPresentationStyle = .fullScreen
        self.present(callVC, animated: true, completion: nil)
    }
}

Customize the foreground view

If you want to add some custom components at the top level of the view, such as you want to display the user avatars when the video view is displayed, add user-level icons, etc., then you can use ZegoUIKitPrebuiltCallVCDelegate.getForegroundView protocol. The getForegroundView requires you (the developer) to return a custom view that will be placed at the top of the view.

Here is the reference code:

class ViewController: UIViewController {

    let selfUserID: String = "userID"
    let selfUserName: String = "userName"
    let yourAppID: UInt32 = YourAppID 
    let yourAppSign: String = YourAppSign
    let callID: String = "testCallID"

    @IBOutlet weak var userIDLabel: UILabel! {
        didSet {
            userIDLabel.text = selfUserID
        }
    }
    @IBOutlet weak var userNameLabel: UILabel! {
        didSet {
            selfUserName = String(format: "zego_%@", selfUserID)
            userNameLabel.text = selfUserName
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func makeNewCall(_ sender: Any) {

        // Modify your custom configurations here.
        let config: ZegoUIKitPrebuiltCallConfig = ZegoUIKitPrebuiltCallConfig(.oneOnOneVideoCall)

        config.turnOnCameraWhenjoining = false;
        config.audioVideoViewConfig.showCameraStateOnView = false;
        config.bottomMenuBarConfig.buttons = [.toggleMicrophoneButton,.hangUpButton,.swtichAudioOutputButton]

        let callVC = ZegoUIKitPrebuiltCallVC.init(yourAppID, appSign: yourAppSign, userID: selfUserID, userName: selfUserName ?? "", callID: callID, config: config)

        callVC.delegate = self

        callVC.modalPresentationStyle = .fullScreen
        self.present(callVC, animated: true, completion: nil)
    }

    func getForegroundView(_ userInfo: ZegoUIKitUser?) -> UIView? {
        return YourCustomView()
    }