IOS 8 में ठीक से पॉपओवर कैसे पेश करें


118

मैं अपने स्विफ्ट iOS 8 ऐप में एक UIPopoverView जोड़ने की कोशिश कर रहा हूं, लेकिन मैं PopoverContentSize प्रॉपर्टी को एक्सेस नहीं कर पा रहा हूं, क्योंकि पॉपओवर सही शेप में नहीं दिखता है। मेरा कोड:

var popover: UIPopoverController? = nil 

    func addCategory() {

    var newCategory = storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: newCategory)
    popover = UIPopoverController(contentViewController: nav)
    popover!.setPopoverContentSize(CGSizeMake(550, 600), animated: true)
    popover!.delegate = self
    popover!.presentPopoverFromBarButtonItem(self.navigationItem.rightBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
}

उत्पादन:

यहां छवि विवरण दर्ज करें

जब मैं UIPopoverPresentationController के माध्यम से एक ही काम कर रहा हूं, तब भी मैं इसे पूरा नहीं करता हूं। यह मेरा कोड है:

func addCategory() {

    var popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: popoverContent)
    nav.modalPresentationStyle = UIModalPresentationStyle.Popover
    var popover = nav.popoverPresentationController as UIPopoverPresentationController
    popover.delegate = self
    popover.popoverContentSize = CGSizeMake(1000, 300)
    popover.sourceView = self.view
    popover.sourceRect = CGRectMake(100,100,0,0)

    self.presentViewController(nav, animated: true, completion: nil)

}

मुझे ठीक वही आउटपुट मिलता है।

मैं अपनी आबादी का आकार कैसे अनुकूलित करूं? किसी भी मदद को बहुत सराहा जाएगा!


डेवलपर साइट पर एक WWDC वीडियो है जिसे "ए लुक इनसाइड प्रेजेंटेशन कंट्रोलर्स" कहा जाता है। यह बताता है कि UIPopoverPresentationController का उपयोग कैसे करें
Wextux

मैंने UIpopoverpretationctontroller के संबंध में ऐप्पल वीडियो के अनुसार अपना प्रश्न संपादित किया है, लेकिन कुछ भी नहीं बदला! क्या आप शायद इस बारे में कुछ भी बदल सकते हैं जो मुझे इस बारे में बदलना चाहिए? वैसे, इनपुट के लिए धन्यवाद!
जोरिस ४१६

जवाबों:


148

ठीक है, एक गृहिणी ने इस पर एक नज़र डाली और यह पता लगाया:

 func addCategory() {

    var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
    var nav = UINavigationController(rootViewController: popoverContent)
    nav.modalPresentationStyle = UIModalPresentationStyle.Popover
    var popover = nav.popoverPresentationController
    popoverContent.preferredContentSize = CGSizeMake(500,600)
    popover.delegate = self
    popover.sourceView = self.view
    popover.sourceRect = CGRectMake(100,100,0,0)

    self.presentViewController(nav, animated: true, completion: nil)

}

ये तरीका है।

आप अब पॉपओवर से बात नहीं करते हैं, आप संपत्ति के आकार को सेट करके, संपत्ति को कॉल करके सामग्री के आकार को देखने के लिए उसके अंदर बात करते हैं preferredContentSize


15
शायद स्पष्ट बताते हुए, लेकिन यह सिर्फ तेजी से संबंधित नहीं है। मुझे अपने obj-c ऐप में भी ऐसा करना पड़ा :)
केविन आर।

4
कोड पर एक और टिप्पणी - आप "var" के बजाय "लेट" का उपयोग कर सकते हैं। Apple उन मामलों के लिए अनुशंसा करता है जहाँ आपको मान को पुन: असाइन करने की आवश्यकता नहीं है।
ईपीज_एड

3
इस iPhone के लिए जीएम में Bugged है। यदि आप सिम्युलेटर में पोर्ट्रेट करते समय प्रस्तुत करने का प्रयास करते हैं, तो यह हमेशा पूर्ण स्क्रीन होता है। यदि आप लैंडस्केप के लिए घूमते हैं, तो यह एक पॉपओवर बन जाता है। यदि आप फिर से चित्र पर वापस घूमते हैं, तो यह एक पॉपओवर रहता है।
jjxtra

1
इसका समाधान यह है कि वर्तमान दृश्य कॉलिंग को पॉपओवर स्थापित करने के लिए। यह ऐप्पल के उदाहरण के बिल्कुल विपरीत है जहां वे आपको वर्तमान दृश्य कॉल कंट्रोलर को पॉपओवर सेट करने के लिए स्पष्ट रूप से बताते हैं।
jjxtra

1
@PychoDad यू इस समाधान यू उल्लेख करने के लिए लिंक प्रदान कर सकते हैं। मैं अभी भी "अटक रहा हूं, जबकि सिम्युलेटर चित्र में है, यह हमेशा पूर्ण स्क्रीन है"। धन्यवाद
निशांत

53

वास्तव में यह उससे बहुत सरल है। स्टोरीबोर्ड में आपको व्यूकंट्रोलर बनाना चाहिए जिसे आप पॉपओवर के रूप में उपयोग करना चाहते हैं और हमेशा की तरह इसके लिए एक व्यूकंट्रोलर क्लास बनाएं। आप जिस ऑब्जेक्ट को पॉपओवर खोलना चाहते हैं, उससे नीचे दिखाया गया एक तर्क दें, इस मामले में UIBarButton"कॉन्फ़िगर" नाम दिया गया है।

यहां छवि विवरण दर्ज करें

"मां के दृष्टिकोण में" UIPopoverPresentationControllerDelegateऔर प्रतिनिधि विधि को लागू करें :

func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
    //do som stuff from the popover
}

prepareForSequeइस तरह से विधि को ओवरराइड करें:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     //segue for the popover configuration window
    if segue.identifier == "yourSegueIdentifierForPopOver" {
        if let controller = segue.destinationViewController as? UIViewController {
            controller.popoverPresentationController!.delegate = self
            controller.preferredContentSize = CGSize(width: 320, height: 186)
        }
    }
}

और आपने कल लिया। और अब आप पॉपओवर दृश्य को किसी अन्य दृश्य के रूप में देख सकते हैं, अर्थात। फ़ील्ड जोड़ें और क्या नहीं! और आप में popoverPresentationController.presentedViewControllerविधि का उपयोग करके सामग्री नियंत्रक की पकड़ है UIPopoverPresentationController

इसके अलावा एक iPhone पर आपको अधिलेखित करना होगा

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {

        return UIModalPresentationStyle.none
    } 

28

मुझे इस बात का पूरा उदाहरण मिला कि यह सब कैसे काम करना है ताकि आप हमेशा एक पॉपओवर को प्रदर्शित कर सकें कोई फर्क नहीं पड़ता कि डिवाइस / ओरिएंटेशन https://github.com/frogcjn/AdaptivePopover_iOS8_Swift

कुंजी UIAdaptivePresentationControllerDelegate को लागू करना है

func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle {
    // This *forces* a popover to be displayed on the iPhone
    return .None
}

फिर ऊपर दिए गए उदाहरण का विस्तार करें (कल्पना डिजिटल से):

nav.popoverPresentationController!.delegate = implOfUIAPCDelegate

मैं UIPopoverPresentationControllerDelegate
onmyway133

3
सही, UIPopoverPresentationControllerDelegate UIAdaptivePresentationControllerDelegate का विस्तार करता है। तो, परिभाषा के अनुसार, दोनों में 'अडेप्टिवप्रेसेन्टेशनसेप्टिलफॉरपर्सेंटेशनकंट्रोलर' विधि है। मैंने आधार इंटरफ़ेस प्रदान किया है, जहां ऐप्पल के एपीआई दस्तावेजों में विधि का दस्तावेजीकरण किया गया है।
डेविड हंट

1
ध्यान दें कि यह अनिर्दिष्ट व्यवहार है। दस्तावेज़ कहते हैं इस प्रतिनिधि विधि लौटना चाहिए "या तो UIModalPresentationFullScreenया UIModalPresentationOverFullScreen"। इसके अलावा, "यदि आप इस विधि को लागू नहीं है या किसी भी शैली के अलावा अन्य लौटने UIModalPresentationFullScreenया UIModalPresentationOverFullScreen, प्रस्तुति नियंत्रक से प्रस्तुति शैली को समायोजित कर देता UIModalPresentationFullScreenशैली।"
टॉम

1
वर्तमान दस्तावेज़ीकरण में सलाह दी गई है कि iOS 8.3 आगे से आपको उपयोग करना चाहिए - adaptivePresentationStyleForPresentationController: traitCollection: और वह लौटी शैली होनी चाहिए "UIModalPresentationFieldScreen, UIModalPresentationOverFullScreen, UIModalPresentationFormationFormationFillationFillificationFormationFormationFormationFillification"
डेल

25

स्विफ्ट 2.0

खैर मैंने काम किया। एक नज़र देख लो। StoryBoard में एक ViewController बनाया। PopOverViewController वर्ग के साथ संबद्ध।

import UIKit

class PopOverViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()    
        self.preferredContentSize = CGSizeMake(200, 200)    
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "dismiss:")    
    }    
    func dismiss(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}      

ViewController देखें:

//  ViewController.swift

import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate
{
    func showPopover(base: UIView)
    {
        if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("popover") as? PopOverViewController {    

            let navController = UINavigationController(rootViewController: viewController)
            navController.modalPresentationStyle = .Popover

            if let pctrl = navController.popoverPresentationController {
                pctrl.delegate = self

                pctrl.sourceView = base
                pctrl.sourceRect = base.bounds

                self.presentViewController(navController, animated: true, completion: nil)
            }
        }
    }    
    override func viewDidLoad(){
        super.viewDidLoad()
    }    
    @IBAction func onShow(sender: UIButton)
    {
        self.showPopover(sender)
    }    
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
        return .None
    }
}  

नोट: फंक शोपओवर (बेस: UIView) विधि ViewDidLoad से पहले रखा जाना चाहिए। आशा करता हूँ की ये काम करेगा !


हाय @ अलाविन, मैं मानचित्र एनोटेशन से एक दृश्य पॉपअप करने जा रहा हूं। इसलिए मैंने वैसा ही किया जैसा आपने किया। अंतर यह है कि मैं देखने के बजाय टेबलव्यूकंट्रोलर को आबाद करने जा रहा हूं। अब समस्या डेलिगेट पद्धति को नहीं मार रही है। "popoverPresentationControllerDidDismissPopover"। जब मैं नियंत्रक को खारिज करता हूं। क्या आप मदद कर सकते हैं ? (प्रश्न पोस्ट से संबंधित नहीं है)
सबिन के कुरीकोस

1
एक showPopover(base: UIView)विधि को पहले क्यों रखा जाना चाहिए viewDidLoad()?
एमान्तस

15

IOS9 में UIPopoverController का मूल्यह्रास किया गया है। तो iOS9.x के ऊपर Objective-C संस्करण के लिए नीचे दिए गए कोड का उपयोग कर सकते हैं,

- (IBAction)onclickPopover:(id)sender {
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
UIViewController *viewController = [sb instantiateViewControllerWithIdentifier:@"popover"];

viewController.modalPresentationStyle = UIModalPresentationPopover;
viewController.popoverPresentationController.sourceView = self.popOverBtn;
viewController.popoverPresentationController.sourceRect = self.popOverBtn.bounds;
viewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
[self presentViewController:viewController animated:YES completion:nil]; }

प्रश्न विशेष रूप से स्विफ्ट के लिए पूछता है, न कि ऑब्जेक्टिव-सी के लिए।
एरिक आया

8

यहाँ मैं "Joris416" स्विफ्ट कोड को Objective-c,

-(void) popoverstart
{
    ViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"PopoverView"];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:controller];
    nav.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController *popover = nav.popoverPresentationController;
    controller.preferredContentSize = CGSizeMake(300, 200);
    popover.delegate = self;
    popover.sourceView = self.view;
    popover.sourceRect = CGRectMake(100, 100, 0, 0);
    popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
    [self presentViewController:nav animated:YES completion:nil];
}

-(UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller
{
    return UIModalPresentationNone;
}

ADD को याद रखें
UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate


प्रश्न विशेष रूप से स्विफ्ट के लिए पूछता है, न कि ऑब्जेक्टिव-सी के लिए।
एरिक आया

4

यह iOS8 Day-by-Day ब्लॉग पर सबसे अच्छा समझाया गया है

संक्षेप में, एक बार जब आप अपना UIViewController का modalPresentationStyle .Popover सेट कर लेते हैं, तो आप नियंत्रकों की पॉपओवरप्रेशनशनकंट्रोलर संपत्ति के माध्यम से UIPopoverPresentationClass (एक नया iOS8 वर्ग) प्राप्त कर सकते हैं।


3

मैंने ऊपर इमेजिनेशन डिजिटल्स के एक उद्देश्य-सी संस्करण का उत्तर दिया। मुझे नहीं लगता कि मैंने कुछ भी याद किया क्योंकि यह प्रारंभिक परीक्षण के तहत काम करने के लिए लगता है, अगर आप कुछ जानते हैं तो मुझे बताएं, और मैं इसे अपडेट करूंगा

-(void) presentPopover
{
    YourViewController* popoverContent = [[YourViewController alloc] init]; //this will be a subclass of UIViewController
    UINavigationController* nav =  [[UINavigationController alloc] initWithRootViewController:popoverContent];
    nav.modalPresentationStyle = UIModalPresentationPopover;
    UIPopoverPresentationController* popover = nav.popoverPresentationController;
    popoverContent.preferredContentSize = CGSizeMake(500,600);
    popover.delegate = self;
    popover.sourceRect = CGRectMake(100,100,0,0); //I actually used popover.barButtonItem = self.myBarButton;

    [self presentViewController:nav animated:YES completion:nil];
}

मुझे लगता है कि आपने बाहर छोड़ दिया popover.sourceView = self.view;
ghr

प्रश्न विशेष रूप से स्विफ्ट के लिए पूछता है, न कि ऑब्जेक्टिव-सी के लिए।
एरिक आया

4
मुझे इस बात का एहसास है, लेकिन अगर आप ऑब्जेक्टिव-सी खोज रहे हैं, तो भी गूगल आपको यहां लाता है। यही कारण है कि मैं यहाँ समाप्त हुआ।
narco

3

एक्सकोड 9.1 / स्विफ्ट 4 के लिए मेरे दो सेंट।

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    override func viewDidLoad(){
        super.viewDidLoad()

        let when = DispatchTime.now() + 0.5

        DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in
            // to test after 05.secs... :)
            self.showPopover(base: self.view)

        })

}


func showPopover(base: UIView) {
    if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "popover") as? PopOverViewController {

        let navController = UINavigationController(rootViewController: viewController)
        navController.modalPresentationStyle = .popover

        if let pctrl = navController.popoverPresentationController {
            pctrl.delegate = self

            pctrl.sourceView = base
            pctrl.sourceRect = base.bounds

            self.present(navController, animated: true, completion: nil)
        }
    }
}


@IBAction func onShow(sender: UIButton){
    self.showPopover(base: sender)
}

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

और इसमें प्रयोग करें:

func adaptivePresentationStyle ...

    return .popover

या: वापसी .pageSheet .... इत्यादि।


2

अपने Viewcontroller में UIAdaptivePresentationControllerDelegate लागू करें। फिर जोड़िए :

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

1

निम्नलिखित में बहुत व्यापक गाइड है कि कैसे पॉपअप को कॉन्फ़िगर और प्रस्तुत किया जाए। https://www.appcoda.com/presentation-controllers-tutorial/

सारांश में, एक व्यवहार्य कार्यान्वयन ( स्विफ्ट 4.2 के लिए मूल लेख सिंटैक्स के कुछ अपडेट के साथ ), तब तक कहीं और से बुलाया जा सकता है, निम्नलिखित कुछ इस तरह होगा:

func showPopover(ofViewController popoverViewController: UIViewController, originView: UIView) {
    popoverViewController.modalPresentationStyle = UIModalPresentationStyle.popover
    if let popoverController = popoverViewController.popoverPresentationController {
        popoverController.delegate = self
        popoverController.sourceView = originView
        popoverController.sourceRect = originView.bounds
        popoverController.permittedArrowDirections = UIPopoverArrowDirection.any
    }
    self.present(popoverViewController, animated: true)
}

इस बारे में बहुत कुछ पहले से ही @mmc से उत्तर में कवर किया गया था, लेकिन लेख में इस्तेमाल किए गए कुछ कोड तत्वों की व्याख्या करने में मदद मिलती है, और यह भी दिखाती है कि इसका विस्तार कैसे किया जा सकता है।

यह iPhone बनाम iPad के लिए प्रस्तुति शैली को संभालने के लिए प्रतिनिधिमंडल का उपयोग करने और पॉपओवर को खारिज करने की अनुमति देने के बारे में बहुत अधिक अतिरिक्त विवरण प्रदान करता है यदि यह कभी भी पूर्ण-स्क्रीन दिखाया गया हो। फिर से, स्विफ्ट 4.2 के लिए अपडेट किया गया :

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

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    if traitCollection.horizontalSizeClass == .compact {
        return UIModalPresentationStyle.none
        //return UIModalPresentationStyle.fullScreen
    }
    //return UIModalPresentationStyle.fullScreen
    return UIModalPresentationStyle.none
}

func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
    switch style {
    case .fullScreen:
        let navigationController = UINavigationController(rootViewController: controller.presentedViewController)
        let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(doneWithPopover))
        navigationController.topViewController?.navigationItem.rightBarButtonItem = doneButton
        return navigationController
    default:
        return controller.presentedViewController
    }
}

// As of Swift 4, functions used in selectors must be declared as @objc
@objc private func doneWithPopover() {
    self.dismiss(animated: true, completion: nil)
}

उम्मीद है की यह मदद करेगा।


0

उन लोगों के लिए जो अध्ययन करना चाहते हैं!

मैंने उन लोगों के लिए एक ओपन सोर्स प्रोजेक्ट बनाया, जो किसी भी डिस्पोजल के लिए पॉपओवर व्यू का अध्ययन और उपयोग करना चाहते हैं। आप यहां प्रोजेक्ट पा सकते हैं। https://github.com/tryWabbit/KTListPopup

KTListNewResize

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.