Я хочу иметь постоянную кнопку в правом нижнем углу моего приложения. Во время всех переключений просмотров кнопка должна оставаться статической. У меня возникли проблемы с выбором того, к какому виду добавить кнопку. Я знаю, что кнопка должна храниться в AppDelegate, но я не знаю, какой другой вид было бы целесообразным добавить, кроме окна. Один недостаток добавления его в окно заключается в том, что при работе приложения в фоновом режиме (например, в телефоне) добавленное добавление строки состояния приведет к нажатию на окно. В общем, добавление его в окно кажется хакерским решением - любые мысли?
Создание кнопки на всех контроллерах представлений
Ответ 1
Да, добавление его в UIWindow было бы крайне хакерским и тонким.
Раскадровка
Если вы используете раскадровки и iOS 5.0, вы сможете использовать представления контейнеров и сделать что-то вроде этого:
Вот еще одна картина, показывающая довольно упрощенную структуру первого контроллера просмотра:
Контроллер представления слева имеет контейнер, а затем представление, которое удерживает кнопку над ним. Контейнер указывает, что навигационный контроллер (прямо справа) должен отображаться внутри себя, эта связь показана стрелкой =([])=>
(формально известной как встроенный сегмент). Наконец, контроллер навигации определяет свой контроллер корневого представления тот, что находится справа.
В общем, первый контроллер представления блины - в виде контейнера с кнопкой сверху, поэтому все, что происходит внутри, должно иметь кнопку сверху.
Использование childViewControllers
ака. Режим "Я ненавижу раскадровки и щенки"
Используя аналогичную структуру для версии раскадровки, вы можете создать контроллер базового представления с помощью своей кнопки, а затем добавить представление, которое станет потом новым "корнем" приложения, снизу.
Чтобы сделать это ясно, позвоните на один контроллер просмотра, на котором установлена кнопка 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;
}
Таким образом, вы можете воспользоваться всеми преимуществами вставки кнопки в окне без всякой вины и "Должен ли я быть программистом?" что он вызывает.
Ответ 2
Потенциально у вас может быть 1 главный "корневой" контроллер представлений, и все остальные контроллеры представлений могут быть контроллерами детского вида, а их представления - дочерними. Тогда они будут иметь свой контент, а кнопка будет в "корневом" контроллере представлений. Но это кажется столь же отрывочным и взломанным, как положить его в окно, и, вероятно, менее удобно.
Ответ 3
Я использую эту кнопку:
@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];
Моя кнопка всегда сверху.
Ответ 4
Попробуйте подклассифицировать класс UIViewController и создать свой собственный с помощью кнопки
Ответ 5
Создайте одноэлементный объект, в котором есть кнопка, чтобы все контроллеры представлений могли ссылаться на нее и добавлять ее в свой подзаголовок или напрямую добавлять в окно.
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;