• Stars
    star
    113
  • Rank 310,115 (Top 7 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 3 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

NavigationViewKit is a NavigationView extension library for SwiftUI.

NavigationViewKit

中文版说明

NavigationViewKit is a NavigationView extension library for SwiftUI.

For more detailed documentation and demo, please visit 用NavigationViewKit增强SwiftUI的导航视图

The extension follows several principles.

  • Non-disruptive

Any new feature does not affect the native functionality provided by Swiftui, especially if it does not affect the performance of Toolbar, NavigationLink in NavigationView

  • Be as easy to use as possible

    Add new features with minimal code

  • SwiftUI native style

    Extensions should be called in the same way as the native SwiftUI as much as possible

NavigationViewManager

Introduction

One of the biggest complaints from developers about NavigationView is that it does not support a convenient means of returning to the root view. There are two commonly used solutions.

  • Repackage the UINavigationController

    A good wrapper can indeed use the many functions provided by UINavigationController, but it is very easy to conflict with the native methods in SwiftUI, so you can't have both.

  • Use procedural `NavigationLink

    Return the programmed NavigationLink (usually isActive) by undoing the root view. This means will limit the variety of NavigationLink options, plus is not conducive to implementation from non-view code.

NavigationViewManager is the navigation view manager provided in NavigationViewKit, it provides the following functions.

  • Can manage all the NavigationView in the application
  • Support to return the root view directly from any view under NavigationView by code
  • Jump to a new view via code from any view under NavigationView (no need to describe NavigationLink in the view)
  • Return to the root view via NotificatiionCenter for any NavigationView in the specified application
  • By NotificatiionCenter, let any NavigationView in the application jump to the new view
  • Support transition animation on and off

Register NavigationView

Since NavigationgViewManager supports multiple navigation views management, you need to register for each managed navigation view.

import NavigationViewKit
NavigationView {
            List(0..<10) { _ in
                NavigationLink("abc", destination: DetailView())
            }
        }
        .navigationViewManager(for: "nv1", afterBackDo: {print("back to root") })

navigationViewManager is a View extension, defined as follows.

extension View {
    public func navigationViewManager(for tag: String, afterBackDo cleanAction: @escaping () -> Void = {}) -> some View
}

for is the name (or tag) of the currently registered NavigationView, afterBackDo is the code segment executed when going to the root view.

The tag of each managed NavigationView in the application needs to be unique.

Returning to the root view from a view

In any sub-view of a registered NavigationView, the return to the root view can be achieved with the following code.

@Environment(\.navigationManager) var nvmanager         

Button("back to root view") {
    nvmanager.wrappedValue.popToRoot(tag:"nv1"){
          	 print("other back")
           }
}

popToRoot is defined as follows.

func popToRoot(tag: String, animated: Bool = true, action: @escaping () -> Void = {})

tag is the registered Tag of the current NavigationView, animated sets whether to show the transition animation when returning to the root view, and action is the further after-back code segment. This code will be executed after the registration code segment (afterBackDo) and is mainly used to pass the data in the current view.

This can be done via the

@Environment(\.currentNaviationViewName) var tag

Get the registered Tag of the current NavigationView, so that the view can be reused in different NavigtionViews.

struct DetailView: View {
    @Environment(\.navigationManager) var nvmanager
    @Environment(\.currentNaviationViewName) var tag
    var body: some View {
        VStack {
            Button("back to root view") {
                if let tag = tag {
                    nvmanager.wrappedValue.popToRoot(tag:tag,animated: false) {
                        print("other back")
                    }
                }
            }
        }
    }
}

Using NotificationCenter to return to the root view

Since the main use of NavigationViewManager in my app is to handle Deep Link, the vast majority of the time it is not called in the view code. So NavigationViewManager provides a similar method based on NotificationCenter.

In the code using :

let backToRootItem = NavigationViewManager.BackToRootItem(tag: "nv1", animated: false, action: {})
NotificationCenter.default.post(name: .NavigationViewManagerBackToRoot, object: backToRootItem)

Returns the specified NavigationView to the root view.

Jump from a view to a new view

Use :

@Environment(\.navigationManager) var nvmanager

Button("go to new View"){
        nvmanager.wrappedValue.pushView(tag:"nv1",animated: true){
            Text("New View")
                .navigationTitle("new view")
        }
}

The definition of pushView is as follows.

func pushView<V: View>(tag: String, animated: Bool = true, @ViewBuilder view: () -> V)

tag is the registered Tag of NavigationView, animation sets whether to show the transition animation, view is the new view. The view supports all definitions native to SwiftUI, such as toolbar, navigationTitle, etc.

At the moment, when transition animation is enabled, title and toolbar will be shown after the transition animation, so the view is a little bit short. I will try to fix it in the future.

Use NotificationCenter to jump to new view

In the code.

let pushViewItem = NavigationViewManager.PushViewItem(tag: "nv1", animated: false) {
                    AnyView(
                        Text("New View")
                            .navigationTitle("第四级视图")
                    )
                }
NotificationCenter.default.post(name:.NavigationViewManagerPushView, object: pushViewItem)

tag is the registered Tag of NavigationView, animation sets whether to show the transition animation, view is the new view. The view supports all definitions native to SwiftUI, such as toolbar, navigationTitle, etc.

At the moment, when transition animation is enabled, title and toolbar will be shown after the transition animation, so the view is a little bit short. I will try to fix it in the future.

Use NotificationCenter to jump to new view

In the code.

DoubleColoumnJustForPadNavigationViewStyle

DoubleColoumnJustForPadNavigationViewStyle is a modified version of DoubleColoumnNavigationViewStyle, its purpose is to improve the performance of DoubleColoumnNavigationViewStyle in landscape on iPhone Max when iPhone and iPad use the same set of code, and different from other iPhone models.

When iPhone Max is in landscape, the NavigationView will behave like iPad with double columns, which makes the application behave inconsistently on different iPhones.

When using DoubleColoumnJustForPadNavigationViewStyle, iPhone Max will still show StackNavigationViewStyle in landscape.

Usage.

NavigationView{
   ...
}
.navigationViewStyle(DoubleColoumnJustForPadNavigationViewStyle())

It can be used directly under swift 5.5

.navigationViewStyle(.columnsForPad)

TipOnceDoubleColumnNavigationViewStyle

The current DoubleColumnNavigationViewStyle behaves differently on iPad in both horizontal and vertical screens. When the screen is vertical, the left column is hidden by default, making it easy for new users to get confused.

TipOnceDoubleColumnNavigationViewStyle will show the left column above the right column to remind the user when the iPad is in vertical screen for the first time. This reminder will only happen once. If you rotate the orientation after the reminder, the reminder will not be triggered again when you enter the vertical screen again.

NavigationView{
   ...
}
.navigationViewStyle(TipOnceDoubleColumnNavigationViewStyle())

It can be used directly under swift 5.5

.navigationViewStyle(.tipColumns)

FixDoubleColumnNavigationViewStyle

In Health Notes, I want the iPad version to always keep two columns displayed no matter in landscape or portrait, and the left column cannot be hidden.

I previously used HStack set of two NavigationView to achieve this effect

Now, the above effect can be easily achieved by FixDoubleColumnNavigationViewStyle in NavigationViewKit directly.

NavigationView{
   ...
}
.navigationViewStyle(FixDoubleColumnNavigationViewStyle(widthForLandscape: 350, widthForPortrait:250))

And you can set the left column width separately for both landscape and portrait states.

For more detailed documentation and demo, please visit My Blog

More Repositories

1

SwiftUIOverlayContainer

SwiftUI Overlay Container is a view container component for SwiftUI. It is a customizable, efficient and convenient view manager.
Swift
335
star
2

SwipeCell

SwipeCell is a SwiftUI library, used to achieve the left and right sliding menu effect similar to the iOS mail app.
Swift
294
star
3

SheetKit

an extension library for SwiftUI sheets.
Swift
100
star
4

Infinite4Pager

Infinite4Pager is a flexible and powerful SwiftUI component that provides infinite scrolling capabilities in four directions: up, down, left, and right. It's perfect for creating image galleries, card decks, or any other content that requires seamless navigation in multiple directions.
Swift
98
star
5

BlogCodes

【肘子的Swift笔记】博文中的代码汇总
Swift
98
star
6

SwiftDataKit

SwiftDataKit allows SwiftData developers to access Core Data objects corresponding to SwiftData elements.
Swift
92
star
7

PersistentHistoryTrackingKit

A library for managing Core Data's Persistent History Tracking
Swift
82
star
8

IsScrolling

As the name suggests, IsScrolling provides a ViewModifier to get the current scrolling state of a ScrollView or List in SwiftUI. IsScrolling has good backward and forward compatibility since it is fully implemented natively in SwiftUI. 正如名称所示,IsScrolling 提供了一个 ViewModifier ,用来获取 SwiftUI 中 ScrollView 或 List 当前的滚动状态。由于完全采用了 SwiftUI 原生的方式实现此功能,因此 IsScrolling 具备了很好的前后兼容性。
Swift
74
star
9

MovieHunter

Swift
43
star
10

ShareData_Demo_For_CoreDataWithCloudKit

Demo for wwdc21-10015,how to share data by Core Data with CloudKit
Swift
29
star
11

Todo

Swift
23
star
12

PublishThemeForFatbobmanBlog

A publish theme and plugin for fatbobman.com.Plugins:TruncateHtmlDescription.TagCount,,Bilibili Video,RssPropertiesSetting and more...
Swift
22
star
13

ObservableDefaults

A Swift library that integrates UserDefaults with the new SwiftUI Observation framework
Swift
19
star
14

CoreDataEvolution

A library aimed at modernizing Core Data by incorporating the elegance and safety of SwiftData-style concurrency.
Swift
17
star
15

SwiftDataConcurrencyDemo

Swift
17
star
16

DismissConfirmSheet

iOS14 multiSheet solution. Includes dismiss gesture control
Swift
14
star
17

MOCloner

A tiny library that implements deep copy of NSManagedObject
Swift
10
star
18

TextFieldFomatAndValidateDemo

Swift
9
star
19

PersistentHistoryTrackingDemo

Persistent History Tracking Demo
Swift
9
star
20

ListExample

SwiftUI List example
Swift
7
star
21

CommandExample

SwiftUI 2.0 Commands example
Swift
3
star
22

SimpleLogger

A simple logging library for Swift 6, providing easy-to-use logging functionalities with support for different log levels and backends.
Swift
2
star
23

SwiftIODemo

Swift
2
star
24

MySingleSoureOfTruthDemo

Swift
2
star
25

local-search-engine-for-Publish

local-search-engine-for-publish
Swift
2
star
26

fatbobman.github.io

HTML
2
star
27

SingleStoreDemo

Swift
2
star
28

ModelActorX

ModelActorX is a Swift library that provides custom macros ModelActorX and MainModelActorX to enhance and extend the functionality of SwiftData's ModelActor.
Swift
1
star
29

ShareCode

Some code snippets for sharing 一些用于分享的代码片段
Swift
1
star
30

blogComments

1
star
31

AstroRSSIssue

Astro
1
star
32

FatBlog

CSS
1
star
33

CoreDataInPreview

演示如何为SwiftUI的Preview提供Core Data数据
Swift
1
star
34

LocalizationDemoForBlogPost

Swift
1
star
35

CustomParseableFormatStyleDemo

Swift
1
star