Jalil
Jalil

Reputation: 1236

How can I turn this from swift to objective-c?

I'm following a tutorial but it is in swift and the project I'm working on it's partially written in Objective-C. I already "translated" half of the code but I can't change this part yet.

// Constrain the top of the button bar to the bottom of the segmented control
buttonBar.topAnchor.constraint(equalTo: segmentedControl.bottomAnchor).isActive = true
buttonBar.heightAnchor.constraint(equalToConstant: 5).isActive = true
// Constrain the button bar to the left side of the segmented control
buttonBar.leftAnchor.constraint(equalTo: segmentedControl.leftAnchor).isActive = true
// Constrain the button bar to the width of the segmented control divided by the number of segments
buttonBar.widthAnchor.constraint(equalTo: segmentedControl.widthAnchor, multiplier: 1 / CGFloat(segmentedControl.numberOfSegments)).isActive = true

I already have this, but I don't know how to put the .isActive part.

[buttonBar.topAnchor constraintEqual:_segmentedControl.bottomAnchor];

How can I do it?

Upvotes: 0

Views: 442

Answers (2)

Caleb
Caleb

Reputation: 124997

I don't know how to put the .isActive part.

Each of the lines you cite does several things. For example:

buttonBar.topAnchor.constraint(equalTo: segmentedControl.bottomAnchor).isActive = true

You have to understand what's going on here in order to be able to convert it to a different language. Let's break it down from left to right:

buttonBar

This is a variable that points to a view of some sort, presumably a UIToolbar, but it doesn't really matter as long as it's a view.

.topAnchor

You're calling the topAnchor accessor method, which will return an NSLayoutAnchor object (in fact, a NSLayoutYAxisAnchor object). Objective-C has similar dot syntax for accessors, so you could say buttonBar.topAnchor there too, but you can also write it as [buttonBar topAnchor], which might help you see what's going on.

.constraint(equalTo: ________)

This is a call to the constraint(equalTo:) method. Objective-C's dot syntax doesn't work when there are parameters involved, so you need the messaging syntax. If you're not sure how to translate the name, just look up the Swift name and then change the docs to show Objective-C: constraintEqualToAnchor:. So this part translates to [_____ constraintEqualToAnchor:_____].

segmentedControl.bottomAnchor

This is the same as above: you're just getting the bottomAnchor property of segmentedControl. The result is used as the parameter to the constraintEqualToAnchor: method. Let's put what we've got so far together:

[[buttonBar topAnchor] constraintEqualTo:[segmentedControl bottomAnchor]]

In other words, you're telling the button bar's top anchor to create a constraint that will make it equal to the segment control's bottom anchor. That constraint is returned by the constraintEqualTo: method, which brings us to the last part:

.isActive = true

Here you're setting the isActive property of the constraint returned by constraintEqualTo:. So, in Objective-C, you've got:

[[[buttonBar topAnchor] constraintEqualTo:[segmentedControl bottomAnchor]] setActive:YES];

Or, using Obj-C's dot syntax:

[buttonBar.topAnchor constraintEqualTo:segmentedControl.bottomAnchor].active = YES;

Yes but for example how can I multiply in the last line?

That last line is:

buttonBar.widthAnchor.constraint(equalTo: segmentedControl.widthAnchor, multiplier: 1 / CGFloat(segmentedControl.numberOfSegments)).isActive = true

If you followed all of the above, then you can probably see that you're really doing the same thing, just calling a different method to get the constraint. That method is constraint(equalTo:multiplier:) in Swift, or constraintEqualToAnchor:multiplier: in Objective-C. So do the same thing...

[_____ constraintEqualToAnchor:_____ multiplier:_____].active = YES;

Now just fill in the blanks:

[buttonBar.widthAnchor constraintEqualToAnchor:segmentedControl.widthAnchor
          multiplier:1/CGFloat(segmentedControl.numberOfSegments)].active = YES;

Upvotes: 2

gadu
gadu

Reputation: 1826

You should be able to do

[buttonBar.topAnchor constraintEqualToAnchor:_segmentedControl.bottomAnchor].active = YES;

Apple docs usually a good place to start:

https://developer.apple.com/documentation/uikit/nslayoutanchor?language=objc

In response to your comment about multipliers again read the docs. For example scrolling down on that we see:

Note:

You never use the NSLayoutAnchor class directly. Instead, use one of its subclasses, based on the type of constraint you wish to create.
- Use NSLayoutXAxisAnchor to create horizontal constraints.
- Use NSLayoutYAxisAnchor to create vertical constraints.
- Use NSLayoutDimension to create constraints that affect the view’s height or width.

So width and height constraints are actually NSLayoutDimension and those have extra methods, specifically: constraintEqualToAnchor:multiplier:

Even if you don't want to reference the docs every time, auto-complete is your friend. Just start typing something like [self.widthAnchor constraint and see what comes up

Upvotes: 3

Related Questions