ios UIViewController以编程方式定位按钮不起作用

Posted

技术标签:

【中文标题】ios UIViewController以编程方式定位按钮不起作用【英文标题】:ios UIViewController programmatically positioning buttons not working 【发布时间】:2012-11-28 05:42:23 【问题描述】:

我想在一个视图中均匀分布四个按钮。在情节提要中,我将按钮放置在纵向视图中,因此间距是正确的。但是我没有找到正确的约束设置来使按钮在任何视图宽度(纵向 iPad 或横向)上均匀分布。因此,我添加了以下代码 sn-p,它使用第一个和第四个按钮作为锚点将按钮移动到所需位置:

// evenly space the buttons
CGPoint leftPoint = self.button1.center;
CGPoint rightPoint = self.button4.center;
CGFloat width = rightPoint.x - leftPoint.x;
leftPoint.x += width / 3;
rightPoint.x -= width / 3;
self.button2.center = leftPoint;
self.button3.center = rightPoint;

定位代码工作正常,但我的困难是找到进行调整的最佳位置。 - (void)viewDidAppear:(BOOL)动画 似乎是最好的地方。但是,如果我继续使用不同的视图,当我返回此视图时,按钮将恢复到它们的初始(故事板约束)指定位置。 viewDidAppear 代码将被再次调用,但它无法成功移动按钮。就好像他们的位置在那个时间点被锁定了一样。

我想我的主要问题是是否有办法使用约束来实现我所追求的均匀间距。或者次要问题是如何覆盖这两个按钮的自动定位。

【问题讨论】:

【参考方案1】:

使用布局约束是一件相对困难的事情,它完全取决于你想要什么。我在这里有一个示例,它创建了 4 个按钮(在代码中)以及 5 个用作按钮之间的分隔符的标签。按钮的大小由它们固有的内容大小决定,并且按钮之间以及按钮与包含视图的边之间的间距都是相同的。

-(void)viewDidLoad 
   [super viewDidLoad];

    NSMutableDictionary *viewsDict = [NSMutableDictionary dictionary];
    NSArray *titles = @[@"Short",@"Longer",@"Short",@"The Longest"];
    for (int i=1; i<5; i++) 
        UIButton *b = [UIButton buttonWithType:1];
        [b setTitle:titles[i-1] forState:UIControlStateNormal];
        [b setTranslatesAutoresizingMaskIntoConstraints:NO];
        [viewsDict setObject:b forKey:[NSString stringWithFormat:@"b%d",i]];
    

    for (int i=1; i<6; i++) 
        UILabel *l = [[UILabel alloc ]init];
        [l setTranslatesAutoresizingMaskIntoConstraints:NO];
        [viewsDict setObject:l forKey:[NSString stringWithFormat:@"l%d",i]];
    

    for (id obj in viewsDict.allKeys) 
        [self.view addSubview:viewsDict[obj]];

    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[l1][b1][l2(==l1)][b2][l3(==l1)][b3][l4(==l1)][b4][l5(==l1)]|"
                                                                   options:NSLayoutFormatAlignAllBaseline
                                                                   metrics:nil
                                                                     views:viewsDict];

    NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[b1]-|"
                                                                   options:0
                                                                   metrics:nil
                                                                     views:viewsDict];


    [self.view addConstraints:constraints];
    [self.view addConstraints:constraints2];
 

当视图大小改变时,按钮的间距会自动调整,就像旋转一样。

【讨论】:

谢谢。您的回答将我推向了正确的方向,以弄清楚如何以编程方式添加约束。 满足我的要求,但是你能告诉我用故事板自动布局那么它对我更好还是有什么想法或建议?【参考方案2】:

我得到的解决方案是以编程方式向两个中间按钮(button2 和 button3)添加约束,使它们相对于视图的中间水平放置。这两个约束让我完全删除了手动定位代码。对Evenly space multiple views within a container view 的回答帮助我走上了正轨。

- (void)viewDidLoad

...
    self.button2.translatesAutoresizingMaskIntoConstraints = NO;
    self.button3.translatesAutoresizingMaskIntoConstraints = NO;

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.button2 attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual 
         toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:0.667 constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.button3 attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual 
        toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.333 constant:0]];

【讨论】:

【参考方案3】:

对于几乎任何布局问题的情况,请使用layoutSubviews 方法,它就是这样做的地方。

【讨论】:

我尝试将定位代码移动到 ViewController 的 - (void) viewDidLayoutSubviews 方法,结果相同。第一次出现视图时,按钮的位置正确,但从 segue 返回时,按钮并没有移动到指定的中心点。

以上是关于ios UIViewController以编程方式定位按钮不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式从 iOS Swift 3 中的 XIB 推送和呈现给 UIViewController

ios UIViewController以编程方式定位按钮不起作用

如何在 iOS 中以编程方式从基本 UIViewController 向我的所有视图控制器添加视图

以编程方式创建 UIView 和 UIViewController 并链接在一起的正确方法

以编程方式设置 UIViewController 的视图和生命周期

如何在 Swift 中以编程方式创建新的 UIViewController