Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当从UIBarButtonim呈现时,如何防止方向更改后UIPopoverController直通视图被重置?_Ios_Uipopovercontroller_Uibarbuttonitem - Fatal编程技术网

Ios 当从UIBarButtonim呈现时,如何防止方向更改后UIPopoverController直通视图被重置?

Ios 当从UIBarButtonim呈现时,如何防止方向更改后UIPopoverController直通视图被重置?,ios,uipopovercontroller,uibarbuttonitem,Ios,Uipopovercontroller,Uibarbuttonitem,我有一个UIPopoverController,它是由一个UIBarbuttoneim提供的。我想在popover之外进行触摸,以消除popover。从条形按钮显示弹出框时,其他条形按钮将自动包含在弹出框直通视图中。为了防止出现这种情况,我在演示popover后将passthrough视图设置为nil(或@[]),如下所示: - (IBAction) consoleBarButtonHit:(id)sender { UIViewController *consoleNavigationContr

我有一个UIPopoverController,它是由一个UIBarbuttoneim提供的。我想在popover之外进行触摸,以消除popover。从条形按钮显示弹出框时,其他条形按钮将自动包含在弹出框直通视图中。为了防止出现这种情况,我在演示popover后将passthrough视图设置为nil(或@[]),如下所示:

- (IBAction) consoleBarButtonHit:(id)sender {
UIViewController *consoleNavigationController=[self.storyboard instantiateViewControllerWithIdentifier:@"consoleNavigationController"];
_consolePopoverController=[[UIPopoverController alloc] initWithContentViewController:consoleNavigationController];
_consolePopoverController.delegate=self;

[_consolePopoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

// this must be done _after_ presenting the popover in order to work
_consolePopoverController.passthroughViews=nil;
}
这一切都很好,但是我遇到的问题是,在可以看到popover的情况下旋转设备后,条形按钮会自动重新添加为直通视图,并且不会导致popover被取消

如果我能以某种方式获得bar buttons视图(或rect),那么我可以使用

-presentPopoverFromRect:inView:permittedArrowDirections:animated:
这可能会解决这个问题,但我不知道有什么非黑客的方式可以从一个维吾尔族人那里找到rect/视图

我真的不希望在点击其他条按钮时调用选择器以编程方式取消弹出框,这不是他们的责任,以后可能会给我带来问题


有什么想法吗?

所以我想出了一个解决方案,这有点奇怪,但保持了模块化,效果很好。我创建了一个名为PropertyEnforcer的类,该类将自身注册为对象属性的KVO观察者,并在对象属性发生更改时重新设置该属性

PropertyEnforcer.h:

#import <Foundation/Foundation.h>

@interface PropertyEnforcer : NSObject

+ (void) enforceProperty:(NSString*)keyPath ofObject:(id)target toValue:(id)value;

@end
PropertyEnforcer将自身注册为关联对象,这样我们就不必跟踪它。它将自动注销自己作为KVO观察者的注册,并在UIPopoverController被销毁时被销毁


这是我能想到的最好的、最简单的解决方案。

我选择的解决方案是让
passthroughViews
单独运行,而是禁用/重新启用单个按钮(
UIBarButtonItem
实例)在工具栏或导航栏中,根据其转换显示和取消显示
uipoperpresentationcontroller

(iOS 8:
UIPopoverPresentationController
而不是
UIPopoverController

UIPopoverPresentationController+managedBarButtonItems.h

@interface UIPopoverPresentationController (managedBarButtonItems)

@property (nonatomic, retain) NSArray* managedBarButtonItems;

@end
UIPopoverPresentationController+ManagedBarButtonims.m

#import "UIPopoverPresentationController+managedBarButtonItems.h"

#import <objc/runtime.h>

//
// scope: private, in-terms-of
//

@interface UIBarButtonItem (wasEnabled)

@property (nonatomic) BOOL wasEnabled;

@end

@implementation UIBarButtonItem (wasEnabled)

- (BOOL)wasEnabled
{
    return [objc_getAssociatedObject(self, @selector(wasEnabled)) boolValue];
}

- (void)setWasEnabled:(BOOL)wasIt
{
    objc_setAssociatedObject(self, @selector(wasEnabled), [NSNumber numberWithBool:wasIt], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

// FYI: "Associated objects are released [automatically] after the dealloc method of the original object has finished."

@end

//
// scope: consumable
//

@implementation UIPopoverPresentationController (managedBarButtonItems)

- (NSArray*)managedBarButtonItems
{
    return objc_getAssociatedObject(self, @selector(managedBarButtonItems));
}

- (void)setManagedBarButtonItems:(NSArray*)items
{
    objc_setAssociatedObject(self, @selector(managedBarButtonItems), items, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

// FYI: "Associated objects are released [automatically] after the dealloc method of the original object has finished."

- (void)presentationTransitionDidEnd:(BOOL)completed
{
    [super presentationTransitionDidEnd:completed];

    if (self.barButtonItem && self.managedBarButtonItems)
    {
        for (UIBarButtonItem* button in self.managedBarButtonItems)
        {
            if (button.action != /* actuator */ self.barButtonItem.action)
            {
                button.wasEnabled = button.enabled, button.enabled = NO;
            }
        }
    }
}

- (void)dismissalTransitionDidEnd:(BOOL)completed
{
    [super dismissalTransitionDidEnd:completed];

    if (self.barButtonItem && self.managedBarButtonItems)
    {
        for (UIBarButtonItem* button in self.managedBarButtonItems)
        {
            if (button.action != /* actuator */ self.barButtonItem.action)
            {
                button.enabled = button.wasEnabled;
            }
        }
    }
}

@end
也有可能:

UIAlertController* actionSheet = [UIAlertController
    alertControllerWithTitle:@"Actions" message:nil
        preferredStyle:UIAlertControllerStyleActionSheet];

UIPopoverPresentationController* presenter = actionSheet.popoverPresentationController;

// chosen anchor UIBarButtonItem
presenter.barButtonItem = anchorButton;

// disabled UIViewController buttons
presenter.managedBarButtonItems = self.toolbarItems;
// disabled UINavigationController buttons
presenter.managedBarButtonItems =
    [[NSArray arrayWithArray:self.navigationItem.leftBarButtonItems]
        arrayByAddingObject:self.navigationItem.rightBarButtonItem];
UIAlertController* actionSheet = [UIAlertController
    alertControllerWithTitle:@"Actions" message:nil
        preferredStyle:UIAlertControllerStyleActionSheet];

UIPopoverPresentationController* presenter = actionSheet.popoverPresentationController;

// chosen anchor UIBarButtonItem
presenter.barButtonItem = anchorButton;

// disabled UIViewController buttons
presenter.managedBarButtonItems = self.toolbarItems;
// disabled UINavigationController buttons
presenter.managedBarButtonItems =
    [[NSArray arrayWithArray:self.navigationItem.leftBarButtonItems]
        arrayByAddingObject:self.navigationItem.rightBarButtonItem];