Skip to content

Root view as tabbed swiftui view#1072

Draft
TAKeanice wants to merge 565 commits intodevelopfrom
root-view-tabbed-swiftui
Draft

Root view as tabbed swiftui view#1072
TAKeanice wants to merge 565 commits intodevelopfrom
root-view-tabbed-swiftui

Conversation

@TAKeanice
Copy link
Copy Markdown
Contributor

This is a working preview of the tabbed root view, mostly generated by Claude with my guidance. I have not completely reviewed the code yet, but all basic functionality works, which I can say from basic UI testing.

timbms and others added 30 commits July 25, 2025 06:49
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
remove updateNavigationTitle

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Improving stability of IconView

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Show current image before new image is loaded
Handling of none icon

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
IconView to take full widget only

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…syntax

Included environmentObject for all RowViews where necessary

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
* Include tag 'events' in openapi generation

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* Correcting openapi.json for Content-Type sent by getEvents

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* Removed content application/json for getEvents and regenerated Client.swift and Types.swift
Introduced the struct OpenHABEvent to decode getEvents data. Should be included in openapi.json
Introduced helper openHABEvents(topics: ) to get an AsyncSequence

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* DateTime parsing pushed to OpenAPIService initializer
Removed updateForLongPolling and pollDataForSitemap(subscriptionId) that was not used

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* Adds a complete working SSE command item impl

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* revert dev id

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* remove commented code

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* better screensaver commands

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* new device app options for notifications/sse

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* Adds TTS, finalizes device sytax, updates README

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* remove comment

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* Small cleanups

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

---------

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Co-authored-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
* Include tag 'events' in openapi generation

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* Correcting openapi.json for Content-Type sent by getEvents

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* Removed content application/json for getEvents and regenerated Client.swift and Types.swift
Introduced the struct OpenHABEvent to decode getEvents data. Should be included in openapi.json
Introduced helper openHABEvents(topics: ) to get an AsyncSequence

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* DateTime parsing pushed to OpenAPIService initializer
Removed updateForLongPolling and pollDataForSitemap(subscriptionId) that was not used

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>

* Adds a complete working SSE command item impl

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* revert dev id

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* remove commented code

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* better screensaver commands

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* new device app options for notifications/sse

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* Adds TTS, finalizes device sytax, updates README

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* remove comment

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

* Small cleanups

Signed-off-by: Dan Cunningham <dan@digitaldan.com>

---------

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Dan Cunningham <dan@digitaldan.com>
Co-authored-by: Dan Cunningham <dan@digitaldan.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
timbms and others added 9 commits February 15, 2026 07:47
Replace always-visible search bar with a magnifying glass toolbar
button that toggles search presentation. On iOS 17+ uses the
isPresented parameter of searchable; on older versions falls back
to a custom bottom search bar with focus management.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Replace the UIKit OpenHABRootViewController + SideMenu drawer with a
SwiftUI TabView containing four tabs: Home (MainUI WebView), Sitemaps,
Tiles, and System. Extract background services (SSE, network tracking,
certificate alerts, push notification handling) into AppServicesViewModel.
Remove SideMenu package dependency and deleted files (DrawerView,
OpenHABRootViewController, OpenHABSwiftUIRootView). Persist last-selected
tab across app restarts via HomePreferences.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
…reset, customizable tab bar

- Make notification link in System tab reactive via onReceive
- Show save/cancel in Settings only after user edits a field
- Re-tapping a tab resets it to its root view
- Enable tab bar customization via TabViewCustomization API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Replace direct method calls on @State tab structs with a trigger
pattern for tab re-tap reset, since SwiftUI's internal state
management doesn't propagate changes from external method calls.
Each tab now observes a reset counter via .onChange.

Add tab customization UI in Settings allowing users to reorder tabs
and toggle visibility (except System tab which stays always enabled).
Tab configuration is stored in ApplicationPreferences with backward-
compatible Codable decoding. Tiles now open inline via NavigationStack
instead of modal sheets, and settings toolbar transitions are animated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Show drag handles in the Tabs section by setting edit mode to active,
making it visually clear that rows can be reordered. Move tab
configuration from ApplicationPreferences to HomePreferences so each
home can have its own tab layout. The property is optional for
backward-compatible Codable decoding of existing preferences.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
Add explicit line.3.horizontal icon to each tab row so reorder
capability is always visually indicated. Replace notification-based
tab refresh with Preferences.$currentHomePreferences observer so
the tab bar updates when switching between homes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
…organize project structure

Refactor Preferences to use actor isolation with AsyncChannel (swift-async-algorithms)
instead of @mainactor, consolidate individual screensaver/application preferences into
dedicated structs with migration support, and add PreferencesObserver @observable wrapper
for SwiftUI. Remove all legacy UIKit table view cells, cell providers, and the UIKit
sitemap view controller. Reorganize source files into SwiftUI/ and UIKit/ subdirectories.
Bump Swift tools version to 6.2 and platform targets to 26.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo@karge.de>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
@TAKeanice TAKeanice marked this pull request as draft February 16, 2026 00:58
@TAKeanice TAKeanice requested a review from timbms February 16, 2026 00:59
@timbms
Copy link
Copy Markdown
Contributor

timbms commented Feb 16, 2026

Looks very nice and good to me.
I got many compiler warnings on the first compile. Strange
I am not a full screen user. I assume @digitaldan will have some feedback.

@TAKeanice
Copy link
Copy Markdown
Contributor Author

@timbms the compiler warnings could stem from the version requirement which I pumped up to iOS26 for now (will implement some backward compatibility later).
Another source could be the added package dependencies in the Core package, XCode was very resilient in not recognizing them for a couple of times I tried to compile.

@digitaldan
Copy link
Copy Markdown
Contributor

So i'm not in favor of this approach for a couple of reason. First is that in my very long experience with openHAB, users primarily use sitemaps or the main UI, they don't frequently flip back and forth between the two. Our app does not offer other frequently used features either that a user would often navigate to. So having a permanent menu, taking of space to just show 4 things that once the app is setup, are not actually used much does not seem like a good design choice to me. The other thing is that while we don't typically coordinate too much of our look and feel with the android app, mostly in menus and extra features, this would be a departure from how a primary view of our mainui or sitemaps work from them, having a permanent menu floating above the user's primary content.

I think the floating menu work @timbms is doing is great and really modernizes the look and feel, so my vote is to keep developing that strategy and not pursue a menu bar.

@TAKeanice
Copy link
Copy Markdown
Contributor Author

This was based on a discussion I opened some time ago, where it sounded to me like the decision was to go with a tabbar.

I don't think UI consistency between Android and iOS is very important, otherwise we would do much better using a cross-platform approach. Feature consistency would be nice though.

Using a tabbar is what has been recommended by Apple for years, and with iOS26, it neither has to take up the whole bottom nor do we have to show all tabs at once. That part is configurable in the settings. So every user can decide on what they like to use. On iPad, the tabbar can appear as side menu instead, to be out of the way. I dislike having two sidebars though, one in the home view and one for the application frame, that has always been confusing and inconsistent to me. There has been the added issue that the right side menu has been reachable by a swipe gesture, but that was not obvious at all and there were many situations without a visual navigation option (neither back nor to open the side menu). The tabbar, which is always accessible, improves on that by the well known tap-to-return feature, where a second tab on the selected tab brings the user back to the first page.

@TAKeanice
Copy link
Copy Markdown
Contributor Author

I can imagine a tweak on the current tab bar approach though:
We could allow the users to configure tabs for individual Sitemaps, tiles or MainUI paths, resulting in a very customizable experience tailored to exactly how users want the app to work.

For iPad, I need to play around a little before I can envision the best solution (I think sidebarAdaptable is very neat).

@timbms
Copy link
Copy Markdown
Contributor

timbms commented Feb 16, 2026

I clearly favor the tabbed view over my proposal. To me, it simply feels like the more natural and future-proof direction.

The screen space argument is understandable, but with the display sizes of modern iPhones, I don’t see it as a decisive constraint anymore.

Cross-platform alignment between Android and iOS is not a goal I would prioritize. I believe each app should lean into the native interaction patterns of its platform.

We’ve already seen how the SideMenu “hamburger” approach felt somewhat odd on iOS. I’d prefer we fully embrace the native conventions.

@DigiH
Copy link
Copy Markdown
Contributor

DigiH commented Feb 16, 2026

If I may …

I find this even worse and more distracting than the previously mentioned and settings disableable search field - just out of curiosity, how would the search field be also displayed along with these other tab items?

But as it currently stands:
Home - I never use MainUI., Why should a constantly visible Home tab be there to distract me when it is completely useless for me? I would assume the same applies to other users preferring sitemaps.
Sitemaps - I have one sitemap for the iOS app or for viewing in a desktop web browser, and one sitemap for the Apple Watch. Again, why should there be a constantly visible Sitemap tab, when I never need it to switch between multiple stumps. Also again, I think most sitemap users have little need to constantly switch between sitemaps. And why should users mainly using MainUI be distracted by a useless Sitemap tab?
Tiles - apart from having tried the available two options once in the past I never use any of these options and therefore find a quick access tab at the bottom more distracting than helpful.
Settings - obviously needed, but does it have to be on top of the sitemap? What was wrong with how it is currently accessible?

I do understand the temptation to implement new UI elements, but they should only really be used if the tabs actually include frequently functionality - GitHub Mobile is a good example for this.

Introducing such a tab bar, just because one can and because it looks cool, but populating it with rarely or never used functions, is the wrong way to go in my eyes.

Just my very personal 2 cents worth.

@TAKeanice
Copy link
Copy Markdown
Contributor Author

TAKeanice commented Feb 16, 2026

Hi @DigiH ,

the tabs you mentioned are configurable, even in the current draft state of this PR.
A search bar as right side button next to the tab bar has become standard functionality in apps (see GitHub mobile), but has not been implemented yet, thanks for the suggestion.
The "new" UI element is not for the novelties sake but replaces the side menu's poor UX, so there is nothing really new about it, just a different placement which makes the app clearer and more aligned with iOS interface conventions.

I really like discussing this approach, and I am very open for ideas and changes although I will of course argue for my rationale, but please take a look at the considerations that have already been made, the suggestions in other posts, and maybe actually install and try the solution first, to contribute constructive progress to the topic.

@TAKeanice
Copy link
Copy Markdown
Contributor Author

@timbms thank you for the input, very relieved to read someone liking the approach :) I will still try and make the tabbar contract when scrolling though, because I think this will be convincing for users that only use one of the tabs (e.g. Home or one particular Sitemap) 99% of the time.

@digitaldan and @DigiH what do you think about the minimizing tabbar improvement and about the suggestion to make the tabbar even more configurable, allowing tabs for individual sitemaps, tiles or MainUi paths?

@digitaldan
Copy link
Copy Markdown
Contributor

I'm really sorry, but i do not like having the tab bar visible by default or at all. Our app is simply a viewer for a user's sitemap or main ui, thats where the user customizes the look and feel so it's consistent among all platforms, web, ios or android, our app should get out of the way of that as much as we can.

I stand by my earlier argument, and i think @DigiH makes this point as well, which is we really don't have a use case for frequent switching between parts of the app, so we are just implementing a new UI feature for its own sake.

@DigiH
Copy link
Copy Markdown
Contributor

DigiH commented Feb 16, 2026

I assumed that the tabs might be configurable, but is the whole tab option. , with or without the search option, configurable optional as well?

Let me explain how I approach app UI design.

• I I look at what the main objective of the app is. In case of the openHAB iOS app I think this is nicely displaying either a sitemap or MainUI elements, ideally as clearly visible as possible, without parts of it being covered by unnecessary UI elements - unnecessary here for the main objective.

That is why I proposed making the Search Field optional , as I have never found any use for it, nor can I think anyone would with a well structured sitemap.

I cannot think of any burger menu option or setting which I would want immediately accessible on top of my sitemap.

II'm not saying that some users might not welcome such shortcuts to some of the options and settings. There might have been issues here or requests for it in the forum I am unaware of.

BUT PLEASE make it optional, and don't force it on all users, some of which might just find it unnecessary and distracting, it taking away screen real estate for the main objective.

Just imaging the Books app not having the option of displaying book text full screen, its main objective, without any distracting tabs below or controls above.

TAKeanice and others added 2 commits February 16, 2026 23:23
Refactor SitemapsTab to use navigationDestination(item:) for proper
NavigationStack-based sitemap drill-down, replacing the manual
view-switching approach. Remove redundant inner NavigationStack from
SitemapNavigationView. Adopt sidebarAdaptable tab style with
scroll-to-minimize behavior. Migrate several Preferences.shared call
sites to use async/await pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo.karge@web.de>
…y UIKit views

Replace UIKit-based app launch with a SwiftUI @main App struct using
@UIApplicationDelegateAdaptor. This eliminates UIHostingController and
UIWindow management from AppDelegate entirely. A lightweight SplashView
is shown during async preference migration before swapping to the main
tab root view.

Also removes legacy UIKit view controllers (OpenHABViewController,
OpenHABWebViewController, etc.), fixes a concurrency issue in
IdleTimerService (use AsyncChannel instead of non-Sendable AnyPublisher
across actor boundary), and fixes false-positive edit detection in
SettingsView by guarding onChange until preferences finish loading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tassilo Karge <tassilo@karge.de>
@timbms timbms changed the base branch from develop to openapigen-swiftui February 23, 2026 14:17
@TAKeanice
Copy link
Copy Markdown
Contributor Author

TAKeanice commented Mar 2, 2026

Hi @DigiH , after the previous discussions here, and with the incompatibilities with WebView and more shortcomings that the Tabbar currently has, I would not want to follow this design any more.

I like my idea of having the main menu of the app configurable, but otherwise I think a button in the top right that opens a popup, like in one of @timbms drafts is overall the better choice for now.

So what do you think of a popup menu that sits where the side menu did before (although I'd want to not hide it when there is a button in the MainUI, this just causes technical issues), which is fully configurable with a settings button and buttons for the most needed sitemaps, MainUI pages and homes?

Please don't jump to conclusions regarding the design, if this sounds too vague for you yet, I will make a prototype anyway!

@DigiH
Copy link
Copy Markdown
Contributor

DigiH commented Mar 2, 2026

I like my idea of having the main menu of the app configurable,

Are you still talking about an always visible menu bar for which the individual buttons are configurable, or a setting to make it configurable if such a menu would be visible at all or not?

but otherwise I think a button in the top right that opens a popup, like in one of @timbms drafts is overall the better choice for now.

I generally like popup sheets, when they are appropriate, but if I understand you correctly this would also mean the settings in a popup sheet, and then if using the Bonjour Browser its popup sheet over an already existing popup sheet? I'm sure the UI guidelines have something to say about this somewhere ;) but I might also have complrel;ty misunderstood you.

Please don't jump to conclusions regarding the design, if this sounds too vague for you yet, I will make a prototype anyway!

I think that might be the best idea, so that everyone can see exactly how you envision it. And as direct and open I am with my opinion, I'm just as open to change my mind if something better comes along. And ultimately it's the decision of everyone else as a group.

@DigiH
Copy link
Copy Markdown
Contributor

DigiH commented Mar 2, 2026

@TAKeanice apologies for editing your post! I was so sure I hit Quote and was in my own reply.

That's what can happen when I'm rushing to get to dinner ;) laters …

@DigiH no problem, I can return the favour :D have a nice dinner!

@TAKeanice TAKeanice force-pushed the openapigen-swiftui branch from 1f242b5 to 166a59c Compare March 26, 2026 19:49
Base automatically changed from openapigen-swiftui to develop March 30, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants