mirror of
https://github.com/pointfreeco/swift-composable-architecture.git
synced 2025-12-20 09:11:33 +01:00
* Converted voice memos back to identified array
* update deps
* update docs for DismissEffect
* wip
* Add Sendable conformance to PresentationState (#2086)
* wip
* swift-format
* wip
* wip
* fix some warnings
* docs
* wip
* wip
* Catch some typos in Articles (#2088)
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* docs
* wip
* wip
* docs
* wip
* wip
* wip
* wip
* docs
* docs
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Fix invalid states count for 3 optionals and typos (#2094)
* wip
* wip
* more dismisseffect docs
* fixed some references
* navigation doc corrections
* more nav docs
* fix cancellation tests in release mode
* wrap some tests in #if DEBUG since they are testing expected failures
* update UUIDs in tests to use shorter initializer
* fixed a todo
* wip
* fix merge errors
* wip
* fix
* wip
* wip
* fixing a bunch of todos
* get rid of rawvalue in StackElementID
* more todos
* NavLinkStore docs
* fix swift 5.6 stuff
* fix some standups tests
* fix
* clean up
* docs fix
* fixes
* wip
* 5.6 fix
* wip
* wip
* dont parallelize tests
* updated demo readmes
* wip
* Use ObservedObject instead of StateObject for alert/dialog modifiers.
* integration tests for bad dismissal behavior
* check for runtime warnings in every integration test
* wip
* wip
* wip
* fix
* wip
* wip
* wip
* wip
* wip
* wip
* Drop a bunch of Hashables.
* some nav bug fixes
* wip
* wip
* wip
* fix
* fix
* wip
* wip
* Simplify recording test.
* add concurrent async test
* fix
* wip
* Refact how detail dismisses itself.
* fix
* 5.6 fix
* wip
* wip
* wip
* wip
* Add TestStore.assert.
* Revert "Add TestStore.assert."
This reverts commit a892cccc66.
* add Ukrainian Readme.md (#2121)
* Add TestStore.assert. (#2123)
* Add TestStore.assert.
* wip
* Update Sources/ComposableArchitecture/TestStore.swift
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
* Update Sources/ComposableArchitecture/Documentation.docc/Extensions/TestStore.md
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
* fix tests
---------
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
* Run swift-format
* push for store.finish and presentation
* wip
* move docs around
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Add case subscripts
* wip
* wip
* wip
* 5.7-only
* wip
* wip
* wip
* wip
* fix
* revert store.finish task cancellation
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* add test for presentation scope
* wip
* wip
* wip
* wip
* wip
* cleanup
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Rename ReducerProtocol.swift to Reducer.swift (#2206)
* Hard-deprecate old SwitchStore initializers/overloads
* wip
* wip
* Resolve CaseStudies crash (#2258)
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Bump timeout for CI
* wip
* wip
---------
Co-authored-by: Jackson Utsch <jutechs@gmail.com>
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
Co-authored-by: 유재호 <y73447jh@gmail.com>
Co-authored-by: Dmytro <barabashdmyto@gmail.com>
Co-authored-by: mbrandonw <mbrandonw@users.noreply.github.com>
96 lines
2.6 KiB
Swift
96 lines
2.6 KiB
Swift
import Combine
|
||
import ComposableArchitecture
|
||
import SwiftUI
|
||
import UIKit
|
||
|
||
struct Counter: Reducer {
|
||
struct State: Equatable, Identifiable {
|
||
let id = UUID()
|
||
var count = 0
|
||
}
|
||
|
||
enum Action: Equatable {
|
||
case decrementButtonTapped
|
||
case incrementButtonTapped
|
||
}
|
||
|
||
func reduce(into state: inout State, action: Action) -> Effect<Action> {
|
||
switch action {
|
||
case .decrementButtonTapped:
|
||
state.count -= 1
|
||
return .none
|
||
case .incrementButtonTapped:
|
||
state.count += 1
|
||
return .none
|
||
}
|
||
}
|
||
}
|
||
|
||
final class CounterViewController: UIViewController {
|
||
let viewStore: ViewStoreOf<Counter>
|
||
private var cancellables: Set<AnyCancellable> = []
|
||
|
||
init(store: StoreOf<Counter>) {
|
||
self.viewStore = ViewStore(store, observe: { $0 })
|
||
super.init(nibName: nil, bundle: nil)
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
override func viewDidLoad() {
|
||
super.viewDidLoad()
|
||
|
||
self.view.backgroundColor = .systemBackground
|
||
|
||
let decrementButton = UIButton(type: .system)
|
||
decrementButton.addTarget(self, action: #selector(decrementButtonTapped), for: .touchUpInside)
|
||
decrementButton.setTitle("−", for: .normal)
|
||
|
||
let countLabel = UILabel()
|
||
countLabel.font = .monospacedDigitSystemFont(ofSize: 17, weight: .regular)
|
||
|
||
let incrementButton = UIButton(type: .system)
|
||
incrementButton.addTarget(self, action: #selector(incrementButtonTapped), for: .touchUpInside)
|
||
incrementButton.setTitle("+", for: .normal)
|
||
|
||
let rootStackView = UIStackView(arrangedSubviews: [
|
||
decrementButton,
|
||
countLabel,
|
||
incrementButton,
|
||
])
|
||
rootStackView.translatesAutoresizingMaskIntoConstraints = false
|
||
self.view.addSubview(rootStackView)
|
||
|
||
NSLayoutConstraint.activate([
|
||
rootStackView.centerXAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerXAnchor),
|
||
rootStackView.centerYAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.centerYAnchor),
|
||
])
|
||
|
||
self.viewStore.publisher
|
||
.map { "\($0.count)" }
|
||
.assign(to: \.text, on: countLabel)
|
||
.store(in: &self.cancellables)
|
||
}
|
||
|
||
@objc func decrementButtonTapped() {
|
||
self.viewStore.send(.decrementButtonTapped)
|
||
}
|
||
|
||
@objc func incrementButtonTapped() {
|
||
self.viewStore.send(.incrementButtonTapped)
|
||
}
|
||
}
|
||
|
||
struct CounterViewController_Previews: PreviewProvider {
|
||
static var previews: some View {
|
||
let vc = CounterViewController(
|
||
store: Store(initialState: Counter.State()) {
|
||
Counter()
|
||
}
|
||
)
|
||
return UIViewRepresented(makeUIView: { _ in vc.view })
|
||
}
|
||
}
|