1

I am having an issue with the "depth" of views in UIKit. The ImageView is on top of the TextField, but I want the converse: the text field on top. Below goes an image showing the problem:

enter image description here

FWIW: In SwiftUI, there is ZStack which allows one to easily define what goes on top of what, but I am looking for a solution in UIKit as this project is for a course I am doing to learn UIKit.

The project is on GitHub and is called MemeEditor. This link goes to a commit that presents the aforementioned problem.

Thanks!

zeytin
  • 5,545
  • 4
  • 14
  • 38
Ataias Reis
  • 323
  • 1
  • 9
  • 1
    In UIKit the z-index is specified simply by the order of the views in their superview, therefore just move the stackview with the image to be the first subview. – Sulthan Nov 29 '20 at 12:18

3 Answers3

1

I am looking for a solution in UIKit as this project is for a course I am doing to learn UIKit.

From your question, it sounds like you're looking for a way to do this in code. UIView contains a number of methods that let you change the z-order of subviews, such as insertSubview(_:aboveSubview:) and insertSubview(_:belowSubview:), but since you already have two existing subviews you can use exchangeSubview(at:withSubviewAt:) to just swap the positions of the text view and image in the subviews array.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • I didn't know about ` exchangeSubview(at:withSubviewAt:)`, nice one! I didn't intend to look for a way to do this in code... it is just that I had looked around in the storyboard and assumed wrongly it was too hard (newbie days in uikit, or maybe it is just counter-intuitive in the beginning?) – Ataias Reis Dec 02 '20 at 08:48
0

I actually found two solutions:

Code Solution

From: How can I bring a view in front of another view, in Swift?

With that, I had to add to the View Controller the line

self.view.bringSubviewToFront(textField)

Diff here

Storyboard solution

After a few days, I got feedback on the project and I understood how to do this in the storyboard. Views will show on top when they after down in the hierarchy on the storyboard.

So, I changed from:

wrong hiearchy

to:

correct hierarchy

and the code worked. FWIW the diff is:

diff --git a/MemeEditor/Base.lproj/Main.storyboard b/MemeEditor/Base.lproj/Main.storyboard
index c4fbb55..18400ce 100644
--- a/MemeEditor/Base.lproj/Main.storyboard
+++ b/MemeEditor/Base.lproj/Main.storyboard
@@ -16,6 +16,14 @@
                         <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
+                            <stackView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="l0u-Hb-3mT">
+                                <rect key="frame" x="0.0" y="44" width="414" height="818"/>
+                                <subviews>
+                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="JJT-iB-9fc">
+                                        <rect key="frame" x="0.0" y="0.0" width="414" height="818"/>
+                                    </imageView>
+                                </subviews>
+                            </stackView>
                             <textField contentMode="center" contentHorizontalAlignment="center" contentVerticalAlignment="center" placeholder="TOP MESSAGE" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="cOM-zN-T9a" userLabel="Top Text Field">
                                 <rect key="frame" x="10" y="84" width="394" height="49.5"/>
                                 <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -28,14 +36,6 @@
                                 <fontDescription key="fontDescription" name="HelveticaNeue-CondensedBlack" family="Helvetica Neue" pointSize="40"/>
                                 <textInputTraits key="textInputTraits" autocapitalizationType="allCharacters"/>
                             </textField>
-                            <stackView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="l0u-Hb-3mT">
-                                <rect key="frame" x="0.0" y="44" width="414" height="818"/>
-                                <subviews>
-                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="JJT-iB-9fc">
-                                        <rect key="frame" x="0.0" y="0.0" width="414" height="818"/>
-                                    </imageView>
-                                </subviews>
-                            </stackView>
                             <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OY4-30-dsi">
                                 <rect key="frame" x="0.0" y="813" width="414" height="49"/>
                                 <items>
Ataias Reis
  • 323
  • 1
  • 9
  • 1
    If this solution worked in your case, great, but `bringSubviewToFront(_:)` is a pretty blunt instrument -- there will be times when you don't want to move the obscured subview all the way to the front. – Caleb Dec 01 '20 at 06:43
  • Thanks for pointing it out @Caleb ! I found out another solution so I updated the response to contain both. – Ataias Reis Dec 02 '20 at 08:46
-2

Copy the view you want to be front (⌘C), delete the old one and paste it (⌘V).

nerdintown
  • 115
  • 1
  • 7
  • This is already the case, but it does not influence the order. – Ataias Reis Nov 29 '20 at 12:32
  • This answer was not well explained for a beginner in UIKit like me. After a few days I understood what change was needed in the story board. I need to make the text views appear after (down) in the storyboard hierarchy. – Ataias Reis Dec 02 '20 at 08:37