Wie center eine Schaltfläche mit einem benutzerdefinierten Breite mit autolayout-constraints?
Bitte sehen Sie den folgenden code:
def viewDidLoad
super
self.view.translatesAutoresizingMaskIntoConstraints = false
self.view.backgroundColor = UIColor.whiteColor
@start = UIButton.buttonWithType(UIButtonTypeRoundedRect).tap do |el|
el.translatesAutoresizingMaskIntoConstraints = false
el.setTitle('Start', forState:UIControlStateNormal)
el.addTarget(self, action:'toStartController', forControlEvents:UIControlEventTouchUpInside)
self.view.addSubview(el)
end
self.layout_subviews
end
def layout_subviews
metrics = { 'space' => 8 }
views_dict = {
'superview' => self.view,
'start' => @start
}
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:|-[start(100)]-|',
options: NSLayoutFormatAlignAllCenterX,
metrics: metrics,
views: views_dict))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[start]-|',
options: NSLayoutFormatAlignAllBottom,
metrics: metrics,
views: views_dict))
end
Das problem das ich habe ist H:|-[start(100)]-|
wird nicht funktionieren. Was ich will ist ein button mit einer Breite von 100 mittig auf der X-Achse und an der Unterseite des Bildschirms mit einem Standard-Marge. Sobald ich entfernen Sie die (100)
dies funktioniert, aber die Taste erstreckt sich auf die Breite des Bildschirms minus die Standard-Margen. Wenn ich geben Sie eine benutzerdefinierte Breite ich rechne damit, die Auto-Layout-system kann nicht funktionieren, was die linken und rechten Seitenränder werden sollte. Ich bekomme eine Unable to simultaneously satisfy constraints.
Fehler. Ich denke, das hat etwas zu tun mit den Strichen in H:|-[start(100)]-|
, die brauchen, um eine fluid-Breite zu befestigen, die start
element der superview
, anstatt die Standard-Margen.
Irgendwelche Gedanken auf, wie könnte ich dieses Problem lösen?
Update (Dank ghettopia):
Das funktioniert (beachten Sie, ich bin mit einem UINavigationController
im app-delegate und self.view.translatesAutoresizingMaskIntoConstraints = false
im viewDidLoad
von TestController
ist auskommentiert):
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win|
controller = TestController.alloc.initWithNibName(nil, bundle:nil)
win.rootViewController = UINavigationController.alloc.initWithRootViewController(controller).tap do |root|
root.navigationBarHidden = true
root.wantsFullScreenLayout = true
end
win.makeKeyAndVisible
end
true
end
end
class TestController < UIViewController
def viewDidLoad
super
# self.view.translatesAutoresizingMaskIntoConstraints = false
self.view.backgroundColor = UIColor.blueColor
@button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
@button.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(@button)
views = {
'view' => self.view,
'button' => @button
}
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:[button(100)]', options: 0, metrics: nil, views: views))
self.view.addConstraint(NSLayoutConstraint.constraintWithItem(@button, attribute: NSLayoutAttributeCenterX, relatedBy: NSLayoutRelationEqual, toItem: self.view, attribute: NSLayoutAttributeCenterX, multiplier: 1, constant: 0))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[button]-|', options: 0, metrics: nil, views: views))
end
end
Toll. Jetzt bekomme ich einen blauen Bildschirm mit einer Schaltfläche zentriert auf der X-Achse standardmäßig mit einem Rand an der Unterseite, so wie ich es wollte. Aber von dem, was ich gelesen habe self.view.translatesAutoresizingMaskIntoConstraints = false
ist erforderlich, um Auto-Layout arbeiten. Zu machen, dass passieren, das die so gut funktioniert (merke, ich bin nicht mit einem UINavigationController
dieser Zeit und self.view.translatesAutoresizingMaskIntoConstraints = false
im viewDidLoad
von TestController
verwendet WIRD):
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win|
win.rootViewController = TestController.alloc.initWithNibName(nil, bundle:nil)
win.makeKeyAndVisible
end
true
end
end
class TestController < UIViewController
def viewDidLoad
super
self.view.translatesAutoresizingMaskIntoConstraints = false
self.view.backgroundColor = UIColor.blueColor
@button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
@button.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(@button)
views = {
'view' => self.view,
'button' => @button
}
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:[button(100)]', options: 0, metrics: nil, views: views))
self.view.addConstraint(NSLayoutConstraint.constraintWithItem(@button, attribute: NSLayoutAttributeCenterX, relatedBy: NSLayoutRelationEqual, toItem: self.view, attribute: NSLayoutAttributeCenterX, multiplier: 1, constant: 0))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[button]-|', options: 0, metrics: nil, views: views))
end
end
Aber das scheint nicht wie eine richtige Lösung. Ich brauche eine UINavigationController
um meine app-Struktur. Das Ding ist, wenn ich gar keine der oben genannten Lösungen bekomme ich einen schwarzen Bildschirm mit einer Schaltfläche, die Toten in der Mitte (auf beiden Achsen). Die Aussicht scheint kaputt zu sein:
Gedanken? Soll ich das einfach entfernen self.view.translatesAutoresizingMaskIntoConstraints = false
und vergessen Sie es, oder ist es tatsächlich erforderlich? Wenn es so ist, muss es etwas falsch mit meinem code.
Update 2:
Interessante tutorial: Auto Layout in iOS 6: Einschränkungen Hinzufügen durch den code. Der Autor verwendet nicht self.view.translatesAutoresizingMaskIntoConstraints = false
im viewDidLoad
nur auf Untersichten.
Update 3:
Ich glaube, ich kann löste das schwarze-Bildschirm-problem durch verschieben self.view.translatesAutoresizingMaskIntoConstraints = false
zu den init
Methode statt viewDidLoad
. Nicht sicher, warum dies funktioniert zwar, aber der Bildschirm ist identisch zu dem screenshot nun, wie ich Gegenaktionen in den ersten Platz. Hier ist der aktualisierte code:
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds).tap do |win|
controller = TestController.alloc.initWithNibName(nil, bundle:nil)
win.rootViewController = UINavigationController.alloc.initWithRootViewController(controller).tap do |root|
root.navigationBarHidden = true
root.wantsFullScreenLayout = true
end
win.makeKeyAndVisible
end
true
end
end
class TestController < UIViewController
def init
self.view.translatesAutoresizingMaskIntoConstraints = false
end
def viewDidLoad
super
self.view.backgroundColor = UIColor.blueColor
@button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
@button.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(@button)
views = {
'view' => self.view,
'button' => @button
}
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('H:[button(100)]', options: 0, metrics: nil, views: views))
self.view.addConstraint(NSLayoutConstraint.constraintWithItem(@button, attribute: NSLayoutAttributeCenterX, relatedBy: NSLayoutRelationEqual, toItem: self.view, attribute: NSLayoutAttributeCenterX, multiplier: 1, constant: 0))
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat('V:[button]-|', options: 0, metrics: nil, views: views))
end
end
Du musst angemeldet sein, um einen Kommentar abzugeben.
rootViewController
auf das Fenster-Objekt mit einerUINavigationController
die inits einem anderen controller mit dem code oben. Wenn ich den code ausführen, der hintergrund bleibt schwarz und der botton ist zentriert in der Mitte (auf beiden Achsen). Aber wenn ich Entferne das 'selbst.translatesAutoresizingMaskIntoConstraints = NO; " - Zeile inviewDidLoad
des entsprechendenUIViewController
, der code funktioniert. Aber nicht diese Zeile soll vorhanden sein?rootViewController
des window-Objekts, die direkt auf die entsprechendenUIViewController
anstatt dieUINavigationController
und lassen Sie die Zeileself.translatesAutoresizingMaskIntoConstraints = NO;
imviewDidLoad
intakt. Jetzt ist der code so gut funktioniert. Aber das scheint nicht richtig zu alsUINavigationController
erforderlich ist, um eine app-Struktur.setTranslatesAutoresizingMarkIntoConstraints:NO
für programmatisch erstellte Ansichten. Sorry, ich weiß nicht genug über View-Controller, um Ihnen zu helfen mit dem rest Ihrer Frage. Vielleicht postest screenshots wären neue Antworten.init
Methode. Macht das Sinn?