简体   繁体   English

如何在屏幕中央渲染一个按钮?

[英]How to render a Button on center of the screen?

I am using Google Sign In for my application and by default when it renders, it looks like as attached 我正在为我的应用程序使用Google登录 ,默认情况下,它呈现时看起来像附件

I looked around to see how to add constraints programmatically so that depending on the size of the screen the button lands up on the center of screen, so my code looks like 我环顾四周,看看如何以编程方式添加约束,以便根据屏幕的大小将按钮放到屏幕中央,因此我的代码看起来像

- (void)signInWithGooglePlus {
    GPPSignInButton *signInButton = [[GPPSignInButton alloc] init];
    [signInButton setTranslatesAutoresizingMaskIntoConstraints:NO];
    [signInButton setStyle:kGPPSignInButtonStyleWide];
    [signInButton setColorScheme:kGPPSignInButtonColorSchemeDark];

    NSLayoutConstraint *vConstraint = [NSLayoutConstraint constraintWithItem:signInButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *hConstraint = [NSLayoutConstraint constraintWithItem:signInButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    [self.view addConstraint:vConstraint];
    [self.view addConstraint:hConstraint];

    [self.view addSubview:signInButton];

    GPPSignIn *signIn = [GPPSignIn sharedInstance];
    signIn.shouldFetchGooglePlusUser = YES;
    signIn.shouldFetchGoogleUserEmail = YES;

    signIn.clientID = kClientId;
    signIn.scopes = @[@"profile"];
    signIn.delegate = self;
    [signIn trySilentAuthentication];
}

and is called in 并被称为

- (void)viewDidLoad {
    [super viewDidLoad];
    [self signInWithGooglePlus];
}

When I run it, it fails as 当我运行它时,它失败为

2015-03-14 16:50:11.265 myapp-ios[24332:1661610] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7ff4c0c1b490 GPPSignInButton.centerY == UIView:0x7ff4c0f54930.centerY   (Names: GPPSignInButton:0x7ff4c0f55da0 )>
    When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.
2015-03-14 16:50:11.267 myapp-ios[24332:1661610] View hierarchy unprepared for constraint.
    Constraint: <NSLayoutConstraint:0x7ff4c0c1b490 GPPSignInButton.centerY == UIView:0x7ff4c0f54930.centerY   (Names: GPPSignInButton:0x7ff4c0f55da0 )>
    Container hierarchy: 
<UIView: 0x7ff4c0f54930; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7ff4c0f52d20>>
    View not found in container hierarchy: <GPPSignInButton: 0x7ff4c0f55da0; baseClass = UIButton; frame = (0 0; 226 48); opaque = NO; layer = <CALayer: 0x7ff4c0f542b0>>
    That view's superview: NO SUPERVIEW
2015-03-14 16:50:11.279 myapp-ios[24332:1661610] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view.  Does the constraint reference something from outside the subtree of the view?  That's illegal. constraint:<NSLayoutConstraint:0x7ff4c0c1b490 GPPSignInButton.centerY == UIView:0x7ff4c0f54930.centerY   (Names: GPPSignInButton:0x7ff4c0f55da0 )> view:<UIView: 0x7ff4c0f54930; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7ff4c0f52d20>>'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010bb93a75 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010b828bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010bb939ad +[NSException raise:format:] + 205
    3   Foundation                          0x00000001094d5689 -[NSLayoutConstraint _addToEngine:integralizationAdjustment:mutuallyExclusiveConstraints:] + 187
    4   UIKit                               0x000000010a21bed5 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke_2 + 474
    5   Foundation                          0x00000001094e32fe -[NSISEngine withBehaviors:performModifications:] + 155
    6   UIKit                               0x000000010a21bcdb __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 452
    7   UIKit                               0x000000010a21baee -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 197
    8   UIKit                               0x000000010a21b761 -[UIView(AdditionalLayoutSupport) _initializeHostedLayoutEngine] + 404
    9   UIKit                               0x000000010a21c281 -[UIView(AdditionalLayoutSupport) _layoutEngineCreateIfNecessary] + 53
    10  UIKit                               0x000000010a210bfa -[UIView(UIConstraintBasedLayout) _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 156
    11  UIKit                               0x000000010a210f94 -[UIView(UIConstraintBasedLayout) _tryToAddConstraintWithoutUpdatingConstraintsArray:roundingAdjustment:mutuallyExclusiveConstraints:] + 30
    12  UIKit                               0x000000010a2110bc -[UIView(UIConstraintBasedLayout) _tryToAddConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 243
    13  myapp-ios                        0x0000000108f0fd5d -[GooglePlusLoginViewController signInWithGooglePlus] + 557
    14  myapp-ios                        0x0000000108f0fa7b -[GooglePlusLoginViewController handleAuthentication] + 43
    15  myapp-ios                        0x0000000108f0fa44 -[GooglePlusLoginViewController viewDidLoad] + 228
    16  UIKit                               0x0000000109cba580 -[UIViewController loadViewIfRequired] + 738
    17  UIKit                               0x0000000109cba77e -[UIViewController view] + 27
    18  UIKit                               0x0000000109bd9509 -[UIWindow addRootViewControllerViewIfPossible] + 58
    19  UIKit                               0x0000000109bd98a1 -[UIWindow _setHidden:forced:] + 247
    20  UIKit                               0x0000000109be5f8c -[UIWindow makeKeyAndVisible] + 42
    21  myapp-ios                        0x0000000108f0f483 -[AppDelegate application:didFinishLaunchingWithOptions:] + 627
    22  UIKit                               0x0000000109b8f458 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 248
    23  UIKit                               0x0000000109b90002 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2540
    24  UIKit                               0x0000000109b92e3e -[UIApplication _runWithMainScene:transitionContext:completion:] + 1349
    25  UIKit                               0x0000000109b91d35 -[UIApplication workspaceDidEndTransaction:] + 179
    26  FrontBoardServices                  0x000000010f7a7243 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
    27  CoreFoundation                      0x000000010bac8c7c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    28  CoreFoundation                      0x000000010babe9c5 __CFRunLoopDoBlocks + 341
    29  CoreFoundation                      0x000000010babe785 __CFRunLoopRun + 2389
    30  CoreFoundation                      0x000000010babdbc6 CFRunLoopRunSpecific + 470
    31  UIKit                               0x0000000109b917a2 -[UIApplication _run] + 413
    32  UIKit                               0x0000000109b94580 UIApplicationMain + 1282
    33  myapp-ios                        0x0000000108f0f1e3 main + 115
    34  libdyld.dylib                       0x000000010d104145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Question
How can I place my GPSSignInButton in the center of the screen? 如何将GPSSignInButton在屏幕中央?

在此处输入图片说明

You have to add the signInButton as a subview before you create the constraints; 在创建约束之前,必须将signInButton添加为子视图。 that's why you are getting that error. 这就是为什么您会收到该错误。 Just change the order of your statements. 只需更改语句的顺序即可。

[self.view addSubview:signInButton];
NSLayoutConstraint *vConstraint = [NSLayoutConstraint constraintWithItem:signInButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
NSLayoutConstraint *hConstraint = [NSLayoutConstraint constraintWithItem:signInButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
[self.view addConstraint:vConstraint];
[self.view addConstraint:hConstraint];

EDIT: 编辑:

I didn't know AutoLayout when I posted this answer, please ignore it and use constraints . 发布此答案时我不知道AutoLayout,请忽略它并使用constraints

Old answer: I never used NSLayoutConstraints, but a simple way to do what you want is to set the frame origin of your button like this : 旧答案: 我从未使用过NSLayoutConstraints,但是做您想要做的一个简单方法是像这样设置按钮的框架原点:

[signInButton setFrameOrigin:CGPointMake((self.view.frame.size.width - signInButton.frame.size.width) / 2, (self.view.frame.size.height - signInButton.frame.size.height) / 2)];

As per @iSeven answer, I added the following to my code 根据@iSeven答案,我在代码中添加了以下内容

CGRect frame = signInButton.frame;
frame.origin.x = (self.view.frame.size.width - signInButton.frame.size.width) / 2;
frame.origin.y = (self.view.frame.size.height - signInButton.frame.size.height) / 2;
signInButton.frame = frame;

The entire method now looks like 整个方法现在看起来像

- (void)signInWithGooglePlus {
    GPPSignInButton *signInButton = [[GPPSignInButton alloc] init];
    [signInButton setTranslatesAutoresizingMaskIntoConstraints:NO];
    [signInButton setStyle:kGPPSignInButtonStyleWide];
    [signInButton setColorScheme:kGPPSignInButtonColorSchemeDark];

    CGRect frame = signInButton.frame;
    frame.origin.x = (self.view.frame.size.width - signInButton.frame.size.width) / 2;
    frame.origin.y = (self.view.frame.size.height - signInButton.frame.size.height) / 2;
    signInButton.frame = frame;

    [self.view addSubview:signInButton];
    GPPSignIn *signIn = [GPPSignIn sharedInstance];
    signIn.shouldFetchGooglePlusUser = YES;
    signIn.shouldFetchGoogleUserEmail = YES;

    signIn.clientID = kClientId;
    signIn.scopes = @[@"profile"];
    signIn.delegate = self;
    [signIn trySilentAuthentication];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM