35

Is there a way to simply change the UIPopoverView background color (including its arrow) on iOS8?

(I did read a couple of articles on customizing "UIPopoverControllers". Does this apply here too, meaning the answer is "no"?)

enter image description here

Isn't this something I should be able to address in the prepareForSegue method triggering the popover? How can I reach the according view to change its appearance?

Bernd
  • 11,133
  • 11
  • 65
  • 98

5 Answers5

61

I found the solution. Subclassing is not necessary anymore with iOS8! The background can be accessed and changed like this from within the tableview -> navigation -> popoverPresentationController

    self.navigationController?.popoverPresentationController?.backgroundColor = UIColor.redColor()

More information about this in WWDC session 2014.

Satyam
  • 15,493
  • 31
  • 131
  • 244
Bernd
  • 11,133
  • 11
  • 65
  • 98
10

You can simply modify popover like this:

    let popoverViewController = self.storyboard?.instantiateViewControllerWithIdentifier("popoverSegue")
    popoverViewController!.popoverPresentationController?.delegate = self
    popoverViewController!.modalPresentationStyle = .Popover


    let popoverSize = CGSize(width: 150, height: 60)
    popoverViewController!.preferredContentSize = popoverSize
    let popover = popoverViewController!.popoverPresentationController
    popover?.delegate = self
    popover?.permittedArrowDirections = .Up
    popover?.sourceView = self.view

    //change background color with arrow too!
    popover?.backgroundColor = UIColor.whiteColor()
    popover?.sourceRect = CGRect(x: self.view.frame.width, y: -10, width: 0, height: 0)
    presentViewController(popoverViewController!, animated: true, completion: nil)
Daniel Kuta
  • 1,634
  • 15
  • 24
6

Seems like that popoverPresentationController.backgroundColor no longer works in iOS13.

Popover arrows now appear to take on the color of the popover viewController's view.backgroundColor.

Here's the whole code for the demo below:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let sourceButton = sender as? UIButton, let popover = segue.destination.popoverPresentationController {
        popover.sourceView = sourceButton.superview
        popover.sourceRect = sourceButton.frame
        popover.permittedArrowDirections = [.left]
        popover.delegate = self
        segue.destination.preferredContentSize = CGSize(width: 100, height: 100)
        //popover.backgroundColor = sourceButton.tintColor  //old way
        segue.destination.view.backgroundColor = sourceButton.tintColor  //new way
    }
}

@IBAction func btnTap(_ sender: Any) {
    performSegue(withIdentifier: "popoverSegue", sender: sender)
}

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return .none
}

enter image description here

Travis M.
  • 10,930
  • 1
  • 56
  • 72
3

SwiftUI : Xcode 11.5

Add the .background modifier with the color and add .edgesIgnoringSafeArea modifier.

.popover(isPresented: self.$vm.presentMenu, content: {
        self.menuView
           .background(Color.bgGray.edgesIgnoringSafeArea(.all))
})
Alexander
  • 1,424
  • 18
  • 23
2

Just adding that if you are using SwiftUI inside of a UIPopover or if you are using SwiftUI's popover modifier you can set the background color of the popover by just using a Color in the background, like as in a ZStack.

If you want the arrow colored you can add the .edgesIgnoringSafeArea(.all) modifier to the color in the background so it will extend into the arrow.

SwiftUI example:

import SwiftUI

struct PopoverTest: View {
    @State var showing: Bool = true
    var body: some View {
        Button("Show") {
            self.showing.toggle()
        }
        .popover(isPresented: $showing) {
            ZStack {
                Color.green.edgesIgnoringSafeArea(.all) // will color background and arrow
                Text("Popover!")
            }
        }
    }
}

struct PopoverTest_Previews: PreviewProvider {
    static var previews: some View {
        PopoverTest()
    }
}
Helam
  • 1,385
  • 13
  • 17