We are attempting to re-implement MultiTextConverter in Swift. This time, continuing with the creation of the look and feel of the preferences window, we are adjusting the layout of the conversion tab.
Please see this article for the background.

Adjustment details
In a previous article, we created a conversion tab in the Preferences window. However, the layout needed to be adjusted. The status at this time is as follows.

The following adjustments are made to it in this article.
- Overall margins are small, so create margins on the left and right.
- Vertically centered, so bring it to the top edge.
- Checkboxes are centered, so make it to be left aligned.
Create margins on the left and right
I think that the tab borders and popup button borders are too close together; to create a margin around the view in SwiftUI, use the padding()
modifier.
The content of the conversion tab is implemented in ConverterOptionView
, which has an outermost VStack
, and all the pop-up buttons are in this VStack
.
Creating a margin between the border of the tab and the pop-up button, in other words, creates a margin around the VStack
.
The code is as follows.
struct ConverterOptionView: View {
var body: some View {
VStack {
}
.padding()
}
}
The following is a comparison of before and after with padding()
. A good margin is added.

Align with vertical top edge
Next we adjust the vertical alignment of the whole. The whole is in the VStack
, and the VStack
aligns the subviews vertically; since the VStack
is vertically centered, we place an expandable spacer at the end of the VStack
‘s subviews to bring them to the top edge.
Expandable spacers are Spacer()
in SwiftUI.
Add Spacer()
at the end of the VStack
subview, after GroupBox
.
struct ConverterOptionView: View {
var body: some View {
VStack {
// ...
GroupBox("Shift JIS 機種依存文字のマッピング") {
Picker("読み込み:", selection: $sjisMappingRead) {
Text("macOS").tag(0)
Text("Windows (Code Page 932)").tag(1)
}
Picker("保存:", selection: $sjisMappingWrite) {
Text("macOS").tag(0)
Text("Windows (Code Page 932)").tag(1)
}
}
Spacer()
}
.padding()
}
}
Left-align checkboxes, etc.
The popup buttons and group boxes are resized to fit the size of the tab view, so there is no problem, but the checkboxes are not resized and are centered. This is not correct, so we will change them to left-aligned.
The horizontal align of the subviews in the VStack
can be specified to the argument of the VStack
initializer.
With the next code, the subviews of the VStack are aligned left (leading).
VStack(alignment: .leading)
Create the margin between the checkbox and the group box
At this point, we ran it and got the following window.

I got impreression that the checkbox and the label are too close.
It is fine that create the more margin. We add the Spacer()
and specify its height. To specify the height, we use frame()
modifier.
struct ConverterOptionView: View {
var body: some View {
VStack(alignment: .leading) {
// ...
Toggle("半角カタカナを全角カタカナへ変換する", isOn: $replaceHalfKatakana)
Spacer()
.frame(height: 20)
GroupBox("Shift JIS 機種依存文字のマッピング") {
// ...
}
Spacer()
}
.padding()
}
}
Conclusion
Completed the layout of the conversion tab. At this point it should looks like this.

Resize the window, the layout is adjusted as expected.
Can the Flutter Desktop develop the MultiTextConverter?
MultiTextConverter has no specific device-dependent features. I thought that would be easy to implement in a framework that can support multiple platforms, such as Flutter. Flutter, for example, now supports desktop apps for macOS starting with 3.0.

I started building it with SwiftUI, but I wanted to try Flutter Desktop as well.
I will interrupt for a while to study and review Flutter.