-3

Look at this image, please :

enter image description here

1' problem: i'd like to build it in iPhone SE, 8, 8 Plus and X but i can't do it.

2' problem: I used image and text insets to place the central image above the text. Changing the iPhone devise, and changing the proporsions of the buttons, also changes the arrangement of text and image?

Thank you.

sticky bit
  • 36,626
  • 12
  • 31
  • 42
Claudio F
  • 15
  • 3
  • I would consider using a `UIStackView` in `horizontal` mode to contain the image and text. You could then add these to additional `UIStackView` views to generate a grid, eventually allowing you to constraint the outer most `UIStackView` to the centre of the super view. From there you can generate traits for different devices/layouts or manipulate the constraints directly – MadProgrammer Sep 11 '18 at 23:00
  • Use stackview 's ok, but it have't effects when touched – Nguyen Hoan Sep 12 '18 at 02:28

2 Answers2

0

Start with a UIImageView and UILabel. Constraint the width (or height) to your desired value (this is what you will use to change the size of the image later). Add a "aspect ratio constraint" to the UIImageView and constraint it appropriately (I've used a ratio/multiplier of 1:1, you will need to calculate it based on your original image

Container viewStarting point

Select both the UIImageView and UILabel and "wrap" in a UIStackView

Wrap in StackView

Adjust the properties of the UIStackView to your needs

StackView properties

I used the above to allow the text or image to grow larger without constraining the other element

Okay, the fun part. Copy and paste the UIStackView, align the second UIStackView below the first, so it generates a "column". Select both and wrap in another UIStackView

Multiple StackViews

Update the properties of the new UIStackView...

Properties

Again, I'm focusing on allowing each group to expand without constraining the other

And now I have a container that looks something like...

Container View

Okay, now copy this new UIStackView and paste it, align to the trailing edge (it's not important, but it will make it easier to describe) - this will give you a 2x2 grid. Select the two top most UIStackViews and, again, wrap in another UIStackView

Lots more

Again, I modified the UIStackView properties to Aligment to Center and Distribution to Equal Centering

Okay, now for some fun. Select three of the UIImageViews (personally, I use the top/left one as the master) and remove their constraints (you can use the "Selected View/Clear Constraints option)

Clear Constraints

Select one of the "clean" UIImageViews and Control+Drag to the "master" UIImageView and add width and height constraints, so they will be equal to the master's

Constrain width/height

hint- You can hold down Command to select multiple constraints

Repeat for the other two "clean" UIImageViews

I would know constraint the top most UIStackView to the center of the view, or you can constrain it in any other way you want, but this makes it the primary anchor.

Okay, but why?

Well, now you only need to update a single constraint to update all the images!

Try it. Select the "master" UIImageView, find it's width constraint (you might need to go to the properties sheet) and change it's constant to something else. All the UIImageViews should update!

Equal scaling

At this point, I'd be binding this constraint to the UIViewController so you can modify it within code.

Why stack the stacks this way?

That's a good question, you choices might differ, but, I choose to construct it this way so that the columns will remain entered with each other if the text values are different widths.

Some long text

Is there a simpler way?

Oh, how I wish! Okay, this isn't a "bad" solution, but it does take some thought and about how to lay it out and don't ask me what will happen if the text is split over multiple lines - because it's not pretty.

A "different" approach might be to use a UIView or a container view and then trying to generate the constraints between the images (horizontal and vertical alignment) and the constraint the text between the images in some meaningful way, but that becomes really complex really fast...

Then how do you align them to the parent view? This is why I'd use either a UIView or container view, but then it becomes more complicated as you need to stop the API defining it's own constraints and make sure that you have the correct constraints for the top, bottom, leading and trailing edges

What happens when the text is longer/shorter then the images?! So if you only have some basic text, then the above should work reasonable well and should reasonably maintainable.

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-1

1' problem: i'd like to build it in iPhone SE, 8, 8 Plus and X but i can't do it.
=> why ? what 's your problem?
2':Use stackview 's ok, but it have't effects when touched. You can create a CustomButton class :

class ImageTopButton: UIButton
{
    override func layoutSubviews()
    {
        super.layoutSubviews()
        let size = self.frame.size
        let imageSize = self.imageView!.intrinsicContentSize
        let labelSize = self.titleLabel!.intrinsicContentSize

        let totalHeight = imageSize.height + labelSize.height
        let heightDiff = size.height - totalHeight
        let padding = heightDiff / 2
        let verticalPading:CGFloat = 10

        self.imageView!.center = CGPoint(x: size.width / 2, y: imageSize.height / 2 + padding - verticalPading/2)
        self.titleLabel!.center = CGPoint(x: size.width / 2, y: imageSize.height + padding + labelSize.height / 1.5 + verticalPading/2)
    }
}

You can change verticalPading and set class for UIButton is ImageTopButton
whatever for 1': enter image description here

enter image description here

enter image description here
hope it's useful

Nguyen Hoan
  • 1,583
  • 1
  • 11
  • 18