使用XCode 6.0.1,iOS 8。
我有一个通过Autolayout / constraints放置的UIButton。
我正在尝试以编程方式添加相对于第一个按钮定位的按钮。具体来说,我将它们围绕初始按钮的中心点围成一圈。我用来查找新按钮坐标的数学工作正常,但是:
autolayout&#d; d按钮报告它相对于536x536 superview界面构建器正在使用的原点,而不是设备的实际屏幕大小。
我知道这是因为约束说"容器中的X和Y中心"并且它确实出现在屏幕的中间,但无论设备/屏幕大小如何,frame.origin =(268,268),这是IB中视图的中心(536/2 = 268)。
那么有没有办法以某种方式将其转换为"实际的设备坐标"而不是原始界面构建器坐标?
TIA
编辑:我需要翻译它,无论它是否居中。我意识到我可以获得设备的屏幕尺寸,如果它居中,则除以2。
Edit2:@jrturton - 它在运行时报告其位置在哪里?什么财产?原点和中心都是正确的。无论如何,代码:
创建按钮:
- (void)setupButtons: (int)buttonCount
{
if ((buttonCount > MAX_BUTTONS) || (buttonCount < MIN_BUTTONS)) {
return;
}
float totalRads = degreesToRadians(360.0);
float deltaRads = totalRads / (float)buttonCount;
float radius = 30.0f;
NSMutableArray *buttons = [[NSMutableArray alloc] init];
CGRect centerFrame = self.centerMenuButton.frame;
for (int i = 0; i < buttonCount; i++) {
CGPoint dest = CGPointMake(
(radius * cosf(i * deltaRads) + centerFrame.origin.x),
(radius * sinf(i * deltaRads) + centerFrame.origin.y)
);
CGRect frame = CGRectMake(dest.x, dest.y, 64.0, 64.0);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button setImage:[UIImage imageNamed:@"pink_star"] forState:UIControlStateNormal];
[buttons addObject:button];
}
_menuButtons = [[NSArray alloc] initWithArray:buttons];
}
并显示它们:
- (void)showMenu
{
NSLog(@"showMenu");
for (int i = 0; i < [_menuButtons count]; i++) {
UIButton *btn = [_menuButtons objectAtIndex:i];
NSLog(@"origin: %f, %f", btn.frame.origin.x, btn.frame.origin.y);
[self.view addSubview:btn];
}
_menuOpen = YES;
}
我有一些NSLog用于原始自动布局按钮的中心(约束在IB中设置):
RadialMenuText[14125:6281339] x: 268.000000, y: 268.000000
每个按钮一个(当前为2个):
RadialMenuText[14125:6281339] origin: 298.000000, 268.000000
RadialMenuText[14125:6281339] origin: 238.000000, 267.999997
除了舍入误差之外,数学看起来是半正确的,因为X坐标每次都以正确的方向移动半径。但同样 - 起始坐标不正确,因为自动布局&#d; d按钮正在报告(268,268)。
答案 0 :(得分:1)
我猜您是从setupButtons:
致电viewDidLoad
。在视图控制器从故事板加载其视图之后,但在系统调整当前设备和方向的视图(及其子视图)之前,会发生这种情况。
我建议您通过使用约束来定位按钮而不是设置框架来解决此问题。
除非两个视图位于同一视图层次结构中,否则两个视图之间不能有约束。因此,将按钮添加到setupButtons:
中的视图层次结构中,但将它们设置为隐藏。在showMenu
中,让它们可见。
- (void)setupButtons:(int)buttonCount {
if (buttonCount > MAX_BUTTONS |buttonCount < MIN_BUTTONS) {
return;
}
float totalRads = degreesToRadians(360.0);
float deltaRads = totalRads / (float)buttonCount;
float radius = 30.0f;
NSMutableArray *buttons = [[NSMutableArray alloc] init];
UIView *centerView = self.centerMenuButton;
for (int i = 0; i < buttonCount; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.translatesAutoresizingMaskIntoConstraints = NO;
[button setImage:[UIImage imageNamed:@"pink_star"] forState:UIControlStateNormal];
button.hidden = YES;
[self.view addSubview:button];
[buttons addObject:button];
[button addConstraint:[NSLayoutConstraint
constraintWithItem:button attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeNotAnAttribute
multiplier:0 constant:64]];
[button addConstraint:[NSLayoutConstraint
constraintWithItem:button attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil attribute:NSLayoutAttributeNotAnAttribute
multiplier:0 constant:64]];
CGFloat radians = i * 2 * M_PI / buttonCount;
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:button attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:centerView attribute:NSLayoutAttributeCenterX
multiplier:1 constant:radius * cos(radians)]];
[self.view addConstraint:[NSLayoutConstraint
constraintWithItem:button attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:centerView attribute:NSLayoutAttributeCenterY
multiplier:1 constant:radius * sin(radians)]];
}
_menuButtons = [buttons copy];
}
- (void)showMenu {
NSLog(@"showMenu");
for (int i = 0; i < _menuButtons.count; i++) {
UIButton *btn = _menuButtons[i];
NSLog(@"origin: %f, %f", btn.frame.origin.x, btn.frame.origin.y);
btn.hidden = NO;
}
_menuOpen = YES;
}
答案 1 :(得分:-1)
NSLayoutConstraints在layoutSubviews
之后处理。如果您从自动布局视图中删除NSLayoutConstraints并替换为UIViewAutoresizingFlexible*
常量,则当您在[super layoutSubviews]
覆盖中调用layoutSubviews
时,您的按钮框架将会更新。
@jrturton对于你的中心计算也提出了一个很好的观点。如果您的投诉是被报告的中心是其超级视图中的中心,那么这是预期的行为。如果您希望中心相对于屏幕,则需要使用[[UIScreen mainScreen] convertPoint:point fromView:theView]
转换它。