使按钮在所有视图控制器上保持不变

时间:2013-07-20 03:42:48

标签: ios uiview uiviewcontroller uiwindow

我想在我的应用程序的右下角有一个持久性按钮。在所有视图过渡期间,按钮应保持静态。我在确定添加按钮的视图时遇到问题。我知道按钮应该存储在AppDelegate中,但我不知道除了窗口之外添加它的其他视图是什么意思。将其添加到窗口的一个缺点是,当在后台运行应用程序(即电话)时,添加的状态栏填充将按下窗口。一般来说,将它添加到窗口似乎是一个hacky解决方案 - 任何想法?

5 个答案:

答案 0 :(得分:40)

是的,将它添加到UIWindow会非常hacky和挑剔。

故事板

如果您使用的是Storyboards和iOS 5.0,那么您应该可以使用容器视图并执行以下操作:

MAH BUTTON IS PLEASED

这是另一张图片,展示了第一个视图控制器的相当简单的结构:

enter image description here

左侧的视图控制器有一个容器,然后是一个视图,它将按钮放在它上面。容器指示导航控制器(直接在右侧)应该出现在自身内,该关系由=([])=>箭头(正式名称为 embed segue )显示。最后,导航控制器将其根视图控制器定义为右侧的控制器。

总之,第一个视图控制器在容器视图中使用按钮位于顶部,因此内部发生的所有操作都必须将按钮放在顶部。

使用childViewControllers

又名。 “我讨厌故事板和小狗”模式

使用与Storyboard版本类似的结构,您可以使用其按钮创建基本视图控制器,然后添加视图,该视图将成为应用程序的新“根”,位于下方。

为了清楚起见,让我们调用一个持有按钮FakeRootViewController的视图控制器,以及视控制器,它实际上是应用程序的根目录RootViewController。所有后续视图控制器甚至都不会知道FakeRootViewController高于其他所有人。

FakeRootViewController.m

// The "real" root
#import "RootViewController.h"

// Call once after the view has been set up (either through nib or coded).
- (void)setupRootViewController
{
    // Instantiate what will become the new root
    RootViewController *root = [[RootViewController alloc] <#initWith...#>];

    // Create the Navigation Controller
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root];

    // Add its view beneath all ours (including the button we made)
    [self addChildViewController:nav];
    [self.view insertSubview:nav.view atIndex:0];
    [nav didMoveToParentViewController:self];
}

AppDelegate.m

#import "FakeRootViewController.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    FakeRootViewController *fakeRoot = [[FakeRootViewController alloc] <#initWith...#>];

    self.window.rootViewController = fakeRoot;
    [self.window makeKeyAndVisible];

    return YES;
}

这样,您可以享受在窗口上插入按钮的所有好处,而不会产生任何负罪感和“我真的应该成为程序员吗?”它会导致。

答案 1 :(得分:1)

您可能拥有1个主“根”视图控制器,而您所有其他视图控制器可能是子视图控制器,其视图为子视图。然后他们会有他们的内容,按钮将在“根”视图控制器中。但这看起来就像把它放在窗口里一样粗略和粗俗,可能不太方便。

答案 2 :(得分:0)

我使用这个按钮:

@interface UIPopUpButton : UIImageView <UIPopoverControllerDelegate, UIActionSheetDelegate>
{
    UIPopoverController* popoverController;
    Class popoverClass;
}

- (id) initWithPoint: (CGPoint) point;
- (void) touchesBegan: (NSSet*) touches
            withEvent: (UIEvent*) event;

+ (id) buttonAtPoint: (CGPoint) point;
+ (id) buttonAtOriginalPoint;
+ (void) unhighlight;
+ (void) bringButtonToFront;

@property (nonatomic, retain) UIPopoverController* popoverController;
@property (nonatomic, assign) Class popoverClass;

@end


#import "UIPopUpButton.h"

@implementation UIPopUpButton

static UIPopUpButton* button = nil;
static CGPoint originalPoint;

@synthesize popoverClass;
@synthesize popoverController;

+ (id) buttonAtPoint: (CGPoint) point
{
    if (button == nil)
    {
        button = [[UIPopUpButton alloc] initWithPoint: point];
        originalPoint = point;
        button.popoverClass = [UIPopoverController class];
    }
    else
    {
        button.frame = CGRectMake(point.x, point.y, button.frame.size.width, button.frame.size.height);
    }

    return button;
}

+ (id) buttonAtOriginalPoint
{
    return [self buttonAtPoint: originalPoint];
}

+ (void) unhighlight
{
    button.highlighted = NO;
}

+ (void) bringButtonToFront
{
    [[UIApplication sharedApplication].keyWindow addSubview: [self buttonAtOriginalPoint]];
}

- (id) initWithPoint: (CGPoint) point
{
    UIImage* image1 = [UIImage imageNamed: @"topbutton.png"];
    UIImage* image2 = [UIImage imageNamed: @"topbutton.png"];

    if ((self = [super initWithImage: image1
                    highlightedImage: image2]))
    {
        self.userInteractionEnabled = YES;
        self.frame = CGRectMake(point.x, point.y, self.frame.size.width, self.frame.size.height);
        self.multipleTouchEnabled = NO;
    }

    return self;
}

- (BOOL) isAppCurrStatus
{
    return ([DevToolsClientController sharedInstance].statusOfRootViewController == FrontEndApplication);
}

- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
    UITouch* touch = [touches anyObject];

    if(touch.view == self)
    {
        if (self.popoverController == nil)
        {
            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
            {
                UIActionSheet* actionSheet = [[UIActionSheet alloc] initWithTitle: @"Please choice operation:"
                                                                         delegate: self
                                                                cancelButtonTitle: nil
                                                           destructiveButtonTitle: nil
                                                                otherButtonTitles: nil];
                [actionSheet addButtonWithTitle: @"Cancel"];
                actionSheet.cancelButtonIndex = 0;
                [actionSheet addButtonWithTitle: @"Button 1"];

                actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
                [actionSheet setTag: 0];
                [actionSheet setDelegate: self];
                [actionSheet showInView: [self superview]];
                [actionSheet release];
                [actions release];
            }
            else
            {
                PopoverMenuController* contentViewController = [[PopoverMenuController alloc] init];
                self.popoverController = [[UIPopoverController alloc] initWithContentViewController: contentViewController];
                popoverController.delegate = self;
                [popoverController presentPopoverFromRect: CGRectMake(10.0f, 10.0f, 5.0f, 5.0f)
                                                   inView: self
                                 permittedArrowDirections: UIPopoverArrowDirectionAny
                                                 animated: YES];
                contentViewController.popoverController = self.popoverController;
                [contentViewController reloadData];
            }
        }
        else
        {
            [self.popoverController dismissPopoverAnimated:YES];
            self.popoverController = nil;
        }
    }

    [super touchesBegan: touches withEvent: event];
}



#pragma mark UIActionSheetDelegate implementation

-(void) actionSheet: (UIActionSheet*) actionSheet clickedButtonAtIndex: (NSInteger) buttonIndex
{
    NSNumber* indexAction = [[NSNumber alloc] initWithInt: buttonIndex - 1];

}

- (void) runAction: (NSNumber*) indexAction
{
    [DevToolsPopoverMenuController runAction: [indexAction integerValue]];
}

#pragma mark -
#pragma mark UIPopoverControllerDelegate implementation

- (void) popoverControllerDidDismissPopover: (UIPopoverController*) thePopoverController
{
    if (self.popoverController != nil)
    {
        self.popoverController = nil;
    }
}

- (BOOL) popoverControllerShouldDismissPopover: (UIPopoverController*) thePopoverController
{
    //The popover is automatically dismissed if you click outside it, unless you return NO here
    return YES;
}

@end

呼叫:

     [UIPopUpButton bringButtonToFront];

我的按钮始终位于顶部。

答案 3 :(得分:0)

尝试继承UIViewController类并使用按钮

创建自己的类

答案 4 :(得分:0)

创建一个包含按钮的单例对象,以便所有视图控制器都可以引用它并将其添加到子视图中或直接将其添加到窗口中。

SomeClass.h
@property (nonatomic) UIButton *yourButton;
+(SomeClass*)sharedSomeClass;


SomeClass.m

@synthesize yourButton = _yourButton;

-(id)init
{
self = [super init];
if(self)
{
 _yourButton = [UIButton new];
//Other settings you want for your button
}
return self;
}

+(SomeClass)sharedSomeClass
{
 static SomeClass *sharedSomeClass;
 if (!sharedSomeClass)
  sharedSomeClass = [[super allocWithZone:nil]init];

   return sharedSomeClass;
}

+(void)allocWithZone:(NSZone*)zone
{
 return [self sharedSomeClass];
}

如果您愿意,可以像这样直接访问窗口:

UIWindow *mainwindow = [[[UIApplication sharedApplication]delegate]window];

将SomeClass.h导入视图控制器,并从任何地方访问该按钮

#import "SomeClass.h"

SomeClass *someClass = [SomeClass sharedSomeclass];
UIButton *localButton = someClass.yourButton;