كيف يمكنني ربط طريقة الإجراء لزر شريط أدوات iPad Popover؟

StackOverflow https://stackoverflow.com/questions/2588425

سؤال

أنا أستخدم قالب عرض الانقسام لإنشاء طريقة عرض تقسيم بسيطة لها ، بالطبع ، بوبوف في وضع الصورة. أنا أستخدم الكود الافتراضي الذي تم إنشاؤه بواسطة القالب الذي يضيف/يزيل عنصر شريط الأدوات ويقوم بتعيين وحدة تحكم Popover ويزيله. هاتان الطريقتان هما SplitViewController: WillShowViewController: ... و splitviewController: willhideviewController: ...

أحاول معرفة كيفية جعل البوبوفر يختفي إذا كان المستخدم ينقر على زر شريط الأدوات أثناء عرض البوبوفر. يمكنك جعل البوبوفر يختفي دون تحديد عنصر إذا قمت بالنقر فوق أي مكان خارج البوبوفر ، لكنني أود أيضًا أن أختفي إذا قام المستخدم بنقرل الزر مرة أخرى.

حيث أكون عالقًا ، لا يبدو أن هناك طريقة واضحة وسهلة لربط زر شريط الأدوات. أستطيع أن أقول ، باستخدام مصحح الأخطاء ، أن الإجراء الذي يتم استدعاؤه على الزر هو showmasterinpopover. وأنا جديد في العمل مع المختارين برمجيا ، أعترف.

هل يمكنني كتابة إجراء بطريقة ما ووضعه على عنصر شريط الأدوات دون تجاوز الإجراء الموجود بالفعل؟ على سبيل المثال ، أضف إجراءًا يدعو الخط الموجود الآن؟ أو هل يجب أن أكتب إجراءًا يعرض/يخفي بنفسي (سلوك يتم القيام به خلف الكواليس التي يفترضها وحدة تحكم العرض المنقسمة الآن ؟؟؟).

أو هل أفتقد طريقة سهلة لإضافة هذا السلوك إلى هذا الزر دون تغيير السلوك الحالي الذي يتم إعداده لي؟

شكرًا لك!

هل كانت مفيدة؟

المحلول

لذلك اتضح أنه يمكنك إبعاد البوبوفر عند النقر على Barbuttonitem من خلال تنفيذ طريقة WillPresentViewController من SplitViewController على النحو التالي:

- (void) splitViewController:(UISplitViewController *)svc 
           popoverController: (UIPopoverController *)pc
   willPresentViewController: (UIViewController *)aViewController
{
    if (pc != nil) {
        [pc dismissPopoverAnimated:YES];
    }
}

نصائح أخرى

لذلك ، سيكون لدى Barbuttonitem The UisplitViewController كهدف و showmasterinpopover: كإجراء. لا يمكنني العثور عليه في الوثائق ، لذلك أنا قلق بعض الشيء من أنه ليس من المقبول تسميته ، لكنني حصلت عليه للعمل من خلال تغيير الهدف إلى نفسه (وحدة تحكم العرض) والعمل على طريقة مخصصة ، مثل هذه:

- (void)showMasterInPopover:(id)sender {
    // ...insert custom stuff here...
    [splitViewController showMasterInPopover:sender];
}

ليس لديك مندوب لإدلاء تعليق حقيقي. :-(

@Jann - أنا متأكد تمامًا مما تريده إليزابيث هو قياسي للغاية. على سبيل المثال ، يغلق تطبيق Notes الذي يشحن مسبقًا على جهاز iPad ويفتح البوبوف عند الضغط على زر شريط الأدوات في الزاوية العلوية اليسرى.

أدناه هو الحل الخاص بي. يبدأ الأمر مشابهًا لحل Greenisus ، من خلال تثبيت UISplitViewControllerمعالج أحداث شريط الأدوات. أستخدم علامة في وحدة التحكم الخاصة بي لتتبع ما إذا كان Popover مفتوحًا أم لا. أخيرًا ، للتعامل مع الحالة التي يفتح فيها المستخدم Popover ، ثم يغلقها بالنقر فوق Popover ، أقوم بتنفيذ UIPopoverControllerDelegate بروتوكول.

أولاً ، واجهة وحدة التحكم:

@interface LaunchScene : NSObject <UISplitViewControllerDelegate, UIPopoverControllerDelegate>
{
    UISplitViewController* _splitViewController;    //Shows list UITableView on the left, and details on the right
    UIToolbar* _toolbar;                            //Toolbar for the button that will show the popover, when in portrait orientation
    SEL _svcAction;                                 //The action from the toolbar
    id _svcTarget;                                  //The target object from the toolbar
    UIPopoverController* _popover;                  //The popover that might need to be dismissed
    BOOL _popoverShowing;                           //Whether the popover is currently showing or not
}

-(void) svcToolbarClicked: (id)sender;

أستخدم _SVCACTION و _SVCTARGET لإضافة مخاوف Greenisus من أنه قد لا يتصل بالوظيفة الصحيحة.

فيما يلي تنفيذي. للإيجاز ، لقد حذفت الرمز الذي يثبت uisplitviewController و Virviews. يتم عرض جميع الكود ذي الصلة العرض/إخفاء.

//the master view controller will be hidden so hook the popover
- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController:(UIPopoverController*)pc 
{   
    _popoverShowing = FALSE;
    if(_toolbar == nil) 
    {
        //set title of master button
        barButtonItem.title = @"Title goes here";

        //Impose my selector in between the SVController, and the SVController's default implementation
        _svcTarget = barButtonItem.target;
        _svcAction = barButtonItem.action;
        barButtonItem.target = self;
        barButtonItem.action = @selector(svcToolbarClicked:);

        //create a toolbar
        _toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 1024, 44)];
        [_toolbar setItems:[NSArray arrayWithObject:barButtonItem] animated:YES];
    }

    //add the toolbar to the details view (the second controller in the splitViewControllers array)
    UIViewController* temp = [_splitViewController.viewControllers objectAtIndex:1];
    [temp.view addSubview:_toolbar];
}

فيما يلي وظيفتي التي تستجيب لنقر شريط الأدوات. هذا يتعامل مع الحالة التي يقوم فيها المستخدم بنقر فوق زر شريط الأدوات.

-(void) svcToolbarClicked: (id)sender
{
    if(_popoverShowing)
    {
        [_popover dismissPopoverAnimated:TRUE];
    }
    else 
    {
        //Perform the default SVController implementation
        [_svcTarget performSelector:_svcAction];
    }
    //Toggle the flag
    _popoverShowing = !_popoverShowing;
}

بعض الوظائف من UISplitViewControllerDelegate

//the master view (non-popover) will be shown again (meaning it is going to landscape orientation)
- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)button 
{
    //remove the toolbar
    [_toolbar removeFromSuperview];
}

// the master view controller will be displayed in a popover (i.e. the button has been pressed, and the popover is about to be displayed.  
//Unfortunately triggers when the popover is ALREADY displayed.
- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController 
{   
    _popover = pc; //Grab the popover object  
    _popover.delegate = self;
}

الكود أعلاه يكفي لمعظم الحالات. ومع ذلك ، إذا افتتح المستخدم البوبوفر ، فسيقوم بطرده بالنقر فوق مكان آخر على الشاشة ، _popoverShowing سيحتوي Boolean على قيمة غير صحيحة ، مما سيجبر المستخدم على النقر فوق زر شريط الأدوات مرتين لإعادة فتح البوبوفر. لإصلاح هذا ، تنفيذ UIPopoverControllerDelegate الطريقة ، مثل المقتطف أدناه.

//UIPopoverControllerDelegate method
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
    _popoverShowing = FALSE;
    _popover = nil;
}

استغرق هذا الأمر إلى الأبد لمعرفة ذلك ، والحفر من خلال المستندات و (على ما أظن) معظم أسئلة UISplitViewController على StackOverflow. آمل أن يجدها شخص ما مفيدًا. إذا كان الأمر كذلك ، فأنا أطمح إلى نقاط السمعة. ؛-)

ربما تكون كل شيء يعقدها كثيرًا أو قرأت شيئًا مختلفًا تمامًا عن أن اللاعبين أرادوا فعله ... ولكن ربما ، هذا ما كنت تحاول جميعًا اكتشافه هارديش:

-(void)togglePopOverController {

if ([popOverController isPopoverVisible]) {

[popOverController dismissPopoverAnimated:YES];

} else {

[popOverController presentPopoverFromBarButtonItem:bbiOpenPopOver permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}

}

تكتب إليزابيث:

يمكنك جعل البوبوفر يختفي دون تحديد عنصر إذا قمت بالنقر فوق أي مكان خارج البوبوفر ، لكنني أود أيضًا أن أختفي إذا قام المستخدم بنقرل الزر مرة أخرى.

بادئ ذي بدء ، دعني أقول أن أيا ما أنا على وشك قوله هو أن يؤخذ شخصيا - لا يعني ذلك بهذه الطريقة. كل ذلك يأتي من سنوات من تصميم واجهات البرمجة ودراسة إرشادات واجهة Apple البشرية (بالإضافة إلى وجود مصمم جرافيك هو بشكل متزامن محاولة لتعليمي الطريقة الصحيحة لفعل الأشياء). ويقصده وجهة نظر معارضة وليس كصدق.

ما تقترحه هو مشكلة في واجهة المستخدم بالنسبة لي ، وستكون مشكلة تسبب المتاعب عندما تقوم Apple بمراجعة التطبيق. ليس من المفترض أبدًا أن يكون لديك كائن معروف-يتم إجراء وظيفة لا تؤديها بشكل طبيعي (على سبيل المثال: زر أبداً عروض وثم تصدر عرض/كائن/نافذة. تبديل تفعل هذا).

على سبيل المثال ، يعني الزجاج المكبرة على شريط Navbar البحث (كما هو محدد بواسطة Apple). لديهم في الماضي ، وسيستمرون في المستقبل ، يرفضون التطبيقات التي تستخدم هذا لتكبير الواجهة. فمثلا: Apple ترفض ConvertBot أو أوديسي: درب الدموع (ابحث في الصفحة لها). اللغة في الرفض هي نفسها دائمًا (تمييز ما يمكن أن يستشهدوا به لاستخدامك):

"... يستخدم صور شاشة iPhone/iPod القياسية بطريقة غير قياسية ، مما قد يؤدي إلى ارتباك المستخدم. تغيير سلوك رسومات iPhone القياسية ، أجراءات, ، والصور ، أو محاكاة فشل تلك الرسومات أو الإجراءات أو الصور هي انتهاك لاتفاقية برنامج مطوري iPhone والتي تتطلب تطبيقات للالتزام بإرشادات الواجهة البشرية. "

أيضًا ، إذا كنت تريد حقًا هذه الميزة ، اسأل نفسك: "لماذا؟". إذا كان ذلك لأنك أنت ، نفسك ، مثل ذلك ، فسوف أتخطى ذلك حقًا. سيتم الخلط بين معظم المستخدمين من هذا السلوك ولن يستخدموه بالفعل بسبب لن يعرفوا أنه كان خيارًا للاستخدام. أمضت Apple آخر 3 سنوات في تدريب مستخدمي iPhoneOS على كيفية استخدام عناصر نظام التشغيل والواجهة الخاصة بهم. آخر شيء تريده ، كمبرمج أو مصمم ، هو قضاء بعض الوقت في محاولة تدريب مستخدم على كيفية استخدام تطبيقك. سيقومون بشكل عام بإزالة تطبيقك من أجهزتهم والانتقال إلى تطبيق آخر مماثل بدلاً من إجبار أنفسهم على التعلم لك طريقة لفعل الأشياء.

فقط $ .02

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top