An extension to the standard SwiftUI library.

Overview

SwiftUIX: An extension to the standard SwiftUI library.

CI

SwiftUIX attempts to fill the gaps of the still nascent SwiftUI framework, providing an extensive suite of components, extensions and utilities to complement the standard library. This project is by far the most complete port of missing UIKit/AppKit functionality, striving to deliver it in the most Apple-like fashion possible.

Why

The goal of this project is to complement the SwiftUI standard library, offering hundreds of extensions and views that empower you, the developer, to build applications with the ease promised by the revolution that is SwiftUI.

Requirements

  • iOS 13, macOS 10.15, tvOS 13, or watchOS 6
  • Swift 5.3
  • Xcode 12.4+

Installation

The preferred way of installing SwiftUIX is via the Swift Package Manager.

Xcode 11 integrates with libSwiftPM to provide support for iOS, watchOS, macOS and tvOS platforms.

  1. In Xcode, open your project and navigate to FileSwift PackagesAdd Package Dependency...
  2. Paste the repository URL (https://github.com/SwiftUIX/SwiftUIX) and click Next.
  3. For Rules, select Branch (with branch set to master).
  4. Click Finish.
  5. Open the Project settings, add SwiftUI.framework to the Linked Frameworks and Libraries, set Status to Optional.

Contents

All documentation is available via the repository wiki.

While the project itself is stable and heavily being used in production, its documentation is work-in-progress. Contributions are encouraged and welcomed.

UIKit → SwiftUI

UIKit SwiftUI SwiftUIX
LPLinkView - LinkPresentationView
UIActivityIndicatorView - ActivityIndicator
UIActivityViewController - AppActivityView
UIBlurEffect - BlurEffectView
UICollectionView - CollectionView
UIDeviceOrientation - DeviceLayoutOrientation
UIImagePickerController - ImagePicker
UIPageViewController - PaginationView
UIScreen - Screen
UISearchBar - SearchBar
UIScrollView ScrollView CocoaScrollView
UISwipeGestureRecognizer - SwipeGestureOverlay
UITableView List CocoaList
UITextField TextField CocoaTextField
UIModalPresentationStyle - ModalPresentationStyle
UIViewControllerTransitioningDelegate - UIHostingControllerTransitioningDelegate
UIVisualEffectView - VisualEffectView
UIWindow - WindowOverlay

Activity

  • ActivityIndicator

    ActivityIndicator()
        .animated(true)
        .style(.large)
    
  • AppActivityView - a SwiftUI port for UIActivityViewController.

    AppActivityView(activityItems: [...])
        .excludeActivityTypes([...])
        .onCancel { }
        .onComplete { result in
            foo(result)
        }

Appearance

  • View/visible(_:) - Sets a view's visibility.

Error Handling

  • TryButton - A button capable of performing throwing functions.

Geometry

  • flip3D(_:axis:reverse:) - Flips this view.
  • RectangleCorner - A corner of a Rectangle.
  • ZeroSizeView - A zero-size view for when EmptyView just doesn't work.

Keyboard

  • Keyboard - An object representing the keyboard.
  • View/padding(.keyboard) - Pads this view with the active system height of the keyboard.

Link Presentation:

  • LinkPresentationView

    LinkPresentationView(url: url)
        .frame(height: 192)

Navigation

  • View/navigationBarColor(_:) - Configures the color of the navigation bar for this view.
  • View/navigationBarTranslucent(_:) - Configures the translucency of the navigation bar for this view.
  • View/navigationBarTransparent(_:) - Configures the transparency of the navigation bar for this view.

Pagination

  • PaginationView

    PaginationView(axis: .horizontal) {
        ForEach(0..<10, id: \.hashValue) { index in
            Text(String(index))
        }
    }
    .currentPageIndex($...)
    .pageIndicatorAlignment(...)
    .pageIndicatorTintColor(...)
    .currentPageIndicatorTintColor(...)

Scrolling

  • View/isScrollEnabled(_:) - Adds a condition that controls whether users can scroll within this view. Works with:

    • CocoaList
    • CocoaScrollView
    • CollectionView
    • TextView

    Does not work with SwiftUI's ScrollView.

Search

  • SearchBar - A SwiftUI port for UISearchBar.

    struct ContentView: View {
        @State var isEditing: Bool = false
        @State var searchText: String = ""
        
        var body: some View {
            SearchBar("Search...", text: $searchText, isEditing: $isEditing)
                .showsCancelButton(isEditing)
                .onCancel { print("Canceled!") }
        }
    }
  • View/navigationSearchBar(_:) - Sets the navigation search bar for this view.

    Text("Hello, world!")
        .navigationSearchBar {
            SearchBar("Placeholder", text: $text)
        }
  • View/navigationSearchBarHiddenWhenScrolling(_:) - Hides the integrated search bar when scrolling any underlying content.

Screen

  • Screen - A representation of the device's screen.
  • UserInterfaceIdiom - A SwiftUI port for UIUserInterfaceIdiom.
  • UserInterfaceOrientation - A SwiftUI port for UserInterfaceOrientation.

Scroll

  • ScrollIndicatorStyle - A type that specifies the appearance and interaction of all scroll indicators within a view hierarchy
    • HiddenScrollViewIndicatorStyle - A scroll indicator style that hides all scroll view indicators within a view hierarchy.

Status Bar

  • View/statusItem(id:image:) - Adds a status bar item configured to present a popover when clicked

    Text("Hello, world!")
        .statusItem(id: "foo", image: .system(.exclamationmark)) {
            Text("Popover!")
                .padding()
        }

Text

  • TextView

    TextView("placeholder text", text: $text, onEditingChanged: { editing in
        print(editing)
    })

Visual Effects

  • VisualEffectBlurView - A blur effect view that expands to fill.

    VisualEffectBlurView(blurStyle: .dark)
        .edgesIgnoringSafeArea(.all)

Window

  • View/windowOverlay(isKeyAndVisible:content:) - Makes a window key and visible when a given condition is true.

Contributing

SwiftUIX welcomes contributions in the form of GitHub issues and pull-requests. Please refer the projects section before raising a bug or feature request, as it may already be under progress.

To create an Xcode project for SwiftUIX run bundle install; bundle exec fastlane generate_xcodeproj. To check the automated builds for SwiftUIX run bundle install; bundle exec fastlane build.

License

SwiftUIX is licensed under the MIT License.

Support

SwiftUIX is and will always be free and open. Maintaining SwiftUIX, however, is a time-consuming endeavour. If you're reliant on SwiftUIX for your app/project and would like to see it grow, consider contributing/donating as way to help.

Credits

SwiftUIX is a project of @vmanot.

Comments
  • _PaginationView compilation with Xcode 12 beta

    _PaginationView compilation with Xcode 12 beta

    When compiling with Xcode 12 beta the compiler runs out of steam compiling the Combine code on a 16Gb/256Gb MacBook Pro.

    The error is on line 249 in
    func pageViewController( _ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController ) -> UIViewController? The error says: The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

    wontfix apple-bug compiler-bug 
    opened by writing-shed 38
  • NavigationLink not working inside CocoaScrollView

    NavigationLink not working inside CocoaScrollView

    Any NavigationLink placed inside a CocoaScrollView will not redirect to its destination. The destination view seems to get loaded, but the visual redirect does not happen.

    wontfix apple-bug 
    opened by PKizzle 11
  • Add docs folder for easily wiki contributing

    Add docs folder for easily wiki contributing

    I added a folder called docs, a direct mirror of the wiki. This allows people to open a pull request containing suggested changes to the documentation. Then, @vmanot would have to copy the changes. Still not the most practical, but probably better than uploading files in issues or empty pull requests. Plus, the people who make changes would be recognized. This fixes #80.

    There are all the wiki files in the docs folder, plus a README explaining how to contribute.

    If I should make any changes, let me know.

    opened by ghost 11
  • Can't render multiline text in CocoaList

    Can't render multiline text in CocoaList

    Hi, guys. I want to render a very very long text in CocoaList. But it only render one line and text is clipped with .... I find a solution, that add .fixedSize(horizontal: false, vertical: true) on Text, it's working on SwiftUI native List. But not work on CocoaList.

    Just like this.

    On top of view is CocoaList, bottom of view is List.

    image

    There is my test code.

     VStack {
                CocoaList(items) { item in
                    Text(String(repeating: "\(item.text) ", count: 3))
                        .fixedSize(horizontal: false, vertical: true)
                }
    
                List(items) {
                    item in
                    Text(String(repeating: "\(item.text) ", count: 3))
                        .fixedSize(horizontal: false, vertical: true)
                }
            }
    
    bug sizing-bug 
    opened by Innei 10
  • It is great, but CocoaTextField not support Chinese and Japanese.

    It is great, but CocoaTextField not support Chinese and Japanese.

    Describe the bug It is great, but not support Chinese and Japanese.

    To Reproduce

    Just add a Chinese or Japanese keyboard then switch to it, type any words in CocoaTextField, the first word is correct, type one suggestion word, then type any words always are English.

    help wanted good first issue 
    opened by gliese667c 10
  • Set PageControl tint colors

    Set PageControl tint colors

    I've looked in the source code and there seem to be a few API methods to set the pageIndicatorTintColor and currentPageIndicatorTintColor, but I haven't been able to get the color to actually change.

    I've tried a number of things, including setting the environment key. Below is one example of how I've tried. I also tried adding these modifiers to various levels of the view hierarchy, with no luck. What am I missing?

                    PaginationView(axis: .horizontal) {
                        ForEach(self.items) { feature in
                            ScrollView(.vertical) {
                                FeatureItem(icon: feature.icon!,
                                            title: feature.titleMarkdown!,
                                            description: feature.descriptionMarkdown!)
                                .padding()
                            }
                        }
                    }.pageIndicatorTintColor(CustomColors.darkestGreen.color) // makes a swiftUI color
                    .currentPageIndicatorTintColor(CustomColors.green.color) // makes a swiftUI color
                    .environment(\.currentPageIndicatorTintColor, CustomColors.darkestGreen.color)
                    .environment(\.pageIndicatorTintColor, CustomColors.green.color)
    
    opened by neilpoulin 9
  • Tag Releases

    Tag Releases

    Please can you start tagging releases.

    The changes to the RectangleCorner API made breaking changes to my project which took ages to track down. As everything is running from Master, reverting to previous commits was not easy.

    Tagging release will avoid issues when breaking changes are made.

    Thanks

    documentation 
    opened by MatthewCawley 9
  • PaginationView auto height

    PaginationView auto height

    Is there a way to detect the height of the tallest view inside the PaginationView and make it its frame height? Also, is it possible to make an "Auto Play" so it behaves like a slideshow?

    enhancement wontfix 
    opened by welove 9
  • Can't load dynamic data inside PaginationView

    Can't load dynamic data inside PaginationView

    I have to display some data from api. This is the code:

    PaginationView(axis: .horizontal) {
    
                    ForEach(self.banners, id: \.id) { item in
                   
    URLImage(URL(string:"exampleurl")!)
                        { proxy in
                            proxy.image
                                .resizable()
                        }.frame(width: UIScreen.main.bounds.width - 120, height: 200).aspectRatio(contentMode: .fit)
                            .cornerRadius(15)
    
                    }
                    
                }.onAppear(perform: loadData)
    

    Everything I put inside foreach, even if I put static data it says Cannot convert value of type 'ForEach<[Banner], Int, some View>' to closure result type 'Array'. How can I load data with foreach inside PaginationView?

    enhancement 
    opened by sabina1997 9
  • ObservedPublisher for CurrentValueSubject

    ObservedPublisher for CurrentValueSubject

    ObservedPublisher is a great solution that combines @State and onRecevie into one. But when using CurrentValueSubject there is a problem, ObservedPublisher ignores dropping the first value. I added a line to the code and now it adapts nicely to CurrentValueSubject.

    self._subscription = .init(initialValue: publisher
           .delay(for: .nanoseconds(1), scheduler: RunLoop.main)
           .sink(receiveValue: {
                updateWrappedValue.value($0)
            }))
    
    opened by fatbobman 8
  • CocoaList initialContentAlignment issue

    CocoaList initialContentAlignment issue

    I have noticed an issue with current CocoaList initialContentAlignment implementation. The issue seems to be in UIHostingTableViewController.correctContentOffset function. This function is called whenever content size is updated by the observe value function in the event a view is added to the data source. The issue here is the oldContentSize value: observeValue seems to be called multiple times with values like:

    1. old: 642 new: 452 (discarded by correctContentOffset: more on that later)
    2. old: 452 new: 722 (accepted by correctContentOffset)

    You seem to have noticed this in correctContentOffset:

    guard oldContentSize.maximumDimensionLength < newContentSize.maximumDimensionLength else {
        return
    }
    

    You then calculate the offset like this:

    if initialContentAlignment.vertical == .bottom {
          newContentOffset.y += newContentSize.height - oldContentSize.height
    }
    

    but the delta is way higher than it should be (722-452 instead of 722-642) resulting in a wrong content offset.

    If you remove the said guard the delta would be correct, but the offset will be set even when tableView.frame.size.height < newContentSize.height causing the view to be scrolled to bottom even when the content is not filling the whole frame. You can't even guard on that condition because the condition could match the second call from observeValue and not the first one.

    I'm new to UIKit and I have no idea why it's behaving like that. I'm looking forward to hear your opinion on that. Thanks.

    help wanted 
    opened by MatteCarra 8
  • inputAccessoryView on ios14 will enlarge the inputAccessoryView for long

    inputAccessoryView on ios14 will enlarge the inputAccessoryView for long

    $0.inputAccessoryView({ VStack(alignment: .trailing) { HStack(alignment: .center) { Spacer() Button { isEditing = false onCommit(text ?? "") } label: { Text("完成") .foregroundColor(.blue) .font(.system(size: 14)) } .padding(.trailing) } } }) }) image

    opened by xulidegitHub 0
  • CollectionView .horizontal axes not working

    CollectionView .horizontal axes not working

    I want to create a carousel like view with horizontal scrolling using a CollectionView but it seems that the axes parameter on initializer is ignored. Any ideas?

    import SwiftUI
    import SwiftUIX
    
    struct Model: Identifiable {
        var id: UUID = UUID()
        var name: String
    }
    
    struct ContentView: View {
        @State var animated: Bool = false
        @State var text: String = "test"
        
        var sections = (1...5).map { Model(name: String($0)) }
        var data = (1...99).map { Model(name: String($0)) }
    
        var body: some View {
            CollectionView(.horizontal, sections, id: \.id) { section in
                Section { 
                    ForEach(data) { item in
                        Text(item.name)
                    }
                }
            }
        }
    }
    
    

    Screenshot 2022-09-28 at 5 02 19 PM

    opened by billp 0
  • CocoaHostingController not working

    CocoaHostingController not working

    In SceneDelegate:

    window.rootViewController = CocoaHostingController(mainView: contentView)

    In first view:

    @Environment(\.presenter) var presenter
    ...    
    .onAppear {
      if let presenter = presenter {
          presenter.present(EmptyView())
      }
    ...
    

    presenter is always nil.

    What am I missing? This should work according to the Wiki? https://github.com/SwiftUIX/SwiftUIX/wiki/Dynamic-Presentation

    bug 
    opened by beachcitiessoftware 1
  • Tap Action of Button is not recognized when it is shown inside windowOverlay

    Tap Action of Button is not recognized when it is shown inside windowOverlay

    If I show a group of views inside a list and if a button is shown using windowOverlay modifier, then the tap action on the button is not recognized. However if the same of group of views are presented inside a ScrollView, then the tap action on the button is recognized.

    Following is a trivial example.

    1. ContentView shows the cards either in a ScrollView or using List (in the shown example, I commented out the ScrollView and the cards are presented using the List)
    2. ShowButtonsView has the button which can be tapped
    3. For this example the first Card with text message Card 0 is alone tappable. Upon tapping the Card 0, it presents the button Tap Me which can be tapped.
    struct ContentView: View {
    	
    	@State private var toggleVisible = false
    	
    	var body: some View {
    		
    		//ScrollView {                                 // <-- if it is part of scrollView, tap action of the button shown in ShowButtonsView is recognized
    		List {                                               // <-- if it is part of List, tap action action of the button shown in ShowButtonsView is not recognized
    			ForEach((0...5), id: \.self) { token in
    				
    				CardView(tokenNum: token)
    					.frame(height: 300)
    					.onTapGesture {
    						guard token == 0 else { return }
    						toggleVisible.toggle()
    					}
    					.windowOverlay(isKeyAndVisible: $toggleVisible) {
    						
    						ShowButtonsView()
    							.padding()
    							.frame(width: 100, height: 40)
    							.background(Color.orange)
    					}
    					.padding(.vertical)
    				
    				
    			}
    		}
    		
    	}
    }
    
    
    struct CardView: View {
    	
    	let tokenNum: Int
    	
    	var body: some View {
    		
    		VStack {
    			Spacer()
    			HStack {
    				Spacer()
    				Text("Card \(tokenNum)")
    				Spacer()
    			}
    			Spacer()
    		}
    		.background(Color.gray)
    		.cornerRadius(10)
    		.padding(.horizontal)
    		
    	}
    }
    
    
    
    struct ShowButtonsView: View {
    	var body: some View {
    		VStack {
    			Button {
    				print("I am tapped")
    			} label: {
    				Text("Tap Me")
    					.foregroundColor(.red)
    			}
    
    		}
    	}
    }
    
    

    Thanks for sharing a great library

    opened by ParthaGudivada 0
  • Extra space below CocoaTextField InputAccessoryView on iOS15

    Extra space below CocoaTextField InputAccessoryView on iOS15

    There is some extra white space under inputAccessoryView, only on iOS15. Love this library otherwise!

    CocoaTextField(text: $text)
                .inputAccessoryView(
                    HStack {
                        Spacer()
                        Button("Done") {
    
                        }
                    }
                )
    

    image

    bug sizing-bug 
    opened by ksiwei 1
Releases(0.1.3)
Owner
SwiftUIX
An extension to the standard SwiftUI library.
SwiftUIX
Companion app and XCode extension for adding SwiftUI recipes to your code.

SwiftUI Recipes Companion Free Companion app and XCode extension for adding SwiftUI recipes to your code. Choose from a rich selection of SwiftUI reci

Gordan Glavaš 17 Nov 20, 2022
A Safari extension that redirects Twitter, YouTube, Reddit, and more to privacy friendly alternatives.

Privacy Redirect for Safari A configurable web extension that redirects Twitter, YouTube, Reddit, Google Maps, Google Search, and Google Translate to

null 101 Dec 16, 2022
A Safari Extension for iOS & iPadOS

Duplicator Duplicator is a Safari Extension for iOS and iPadOS that makes duplicating tabs much easier! Check it out on the App Store Privacy Policy ?

Ty Irvine 17 Nov 29, 2022
BTTV-for-Safari - Unofficial BTTV/ FFZ Safari Extension for Twitch

BTTV for Safari This unofficial Safari exention adds support for BTTV and FFZ emotes on Twitch. The extension simply injects the BTTV script from the

Philipp Bolte 14 Dec 26, 2022
Deck is a library that provides a UI to reproduce stacked cards for SwiftUI.

Deck Deck is a library that provides a UI to reproduce stacked cards for SwiftUI. RPReplay_Final1624531727.mov Usage struct Card: View { var data

1amageek 21 Dec 14, 2022
PreviewDevice - library with elegant syntax for Preview Device in SwiftUI

PreviewDevice Requirements Xcode 13.x iOS 13.0+, macOS 10.15+, Mac Catalyst 13.0+, tvOS 13.0+, watchOS 6.0+ Usage Example: import PreviewDevice struc

Anton Paliakov 32 Nov 22, 2022
A SwiftUI dynamic property wrapper for fetching media from your photo library. (iOS, tvOS, macOS)

Media Also available as a part of my SwiftUI+ Collection – just add it to Xcode 13+ A package for simplifying the user of the camera and the user's ph

SwiftUI+ 20 Nov 16, 2022
Joseph Heck 21 Dec 14, 2022
A Swift library for documenting, isolating, and testing SwiftUI, UIKIt & AppKit components.

A Swift library for documenting, isolating, and testing SwiftUI, UIKit & AppKit components. Minimal Example An example demonstrated with the Slider ui

Hayden Pennington 9 Dec 15, 2022
A Library to extend SwiftUI Controls

Introduction SwiftUICompatKit is an open source project that enables accessing controls that has not been developed or have limited functionality in S

Amir Kamali 9 Jun 11, 2020
A simple star rating library for SwiftUI apps on macOS and iOS

DLDRating A simple star rating library for SwiftUI apps on macOS and iOS. Features Installation Usage Styling Credits DLDRating was made by Dionne Lie

null 1 Mar 6, 2022
🎲 100% SwiftUI 2.0, classic 2048 game [SwiftUI 2.0, iOS 14.0+, iPadOS 14.0+, macOS 11.0+, Swift 5.3].

swiftui-2048 If you like the project, please give it a star ⭐ It will show the creator your appreciation and help others to discover the repo. ✍️ Abou

Astemir Eleev 174 Dec 17, 2022
A simple SwiftUI Application to demonstrate creation of UI using SwiftUI.

WatchShop_UI A simple SwiftUI Application to demonstrate creation of UI using SwiftUI. How to run the project ? Fork the project. Run the project usin

Shubham Kr. Singh 12 Apr 15, 2022
E-commerce app built in SwiftUI. Built in the course SwiftUI Masterclass in Udemy.

Touchdown-SwiftUI E-commerce app built in SwiftUI. Built in the course SwiftUI Masterclass in Udemy. Main components and concepts used: @EnvironmentOb

Jorge Martinez 5 Aug 18, 2022
A multiplatform SwiftUI project demonstrating various SwiftUI features.

WikiDemo A multiplatform SwiftUI project demonstrating various SwiftUI features, including creating a master-detail interface. It's a multiplatform ve

Swift Dev Journal 6 Oct 17, 2022
SwiftUI Projects from Udemy SwiftUI Masterclass

SwiftUI Masterclass Repos: AsyncImage (N/A) Fructus (finished): an app for getting information about different fruits. Data comes from json files. Afr

Patrick Spafford 1 Mar 3, 2022
Best architecture for SwiftUI + CombineBest architecture for SwiftUI + Combine

Best architecture for SwiftUI + Combine The content of the presentation: First of the proposed architectures - MVP + C Second of the proposed architec

Kyrylo Triskalo 3 Sep 1, 2022
Weather-swiftui - An example of using SwiftUI

weather-swiftui An example of using SwiftUI Installation Get openweather api key

null 0 Jan 1, 2022