Skip to content

Commit

Permalink
(SwManager) Container to manage several views
Browse files Browse the repository at this point in the history
(SWViewModel) to publish changes on a view
  • Loading branch information
mroffmix committed Oct 14, 2020
1 parent 2811266 commit 7ea14f0
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 75 deletions.
13 changes: 4 additions & 9 deletions Sources/SwipeableView/View/EditActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,12 @@ public struct EditActions: View {

if viewModel.actions.count < 4 && geometry.size.height > 50 {

Text(action.title)
.font(.system(size: 10, weight: .semibold))
.multilineTextAlignment(.center)
.lineLimit(3)




Text(action.title)
.font(.system(size: 10, weight: .semibold))
.multilineTextAlignment(.center)
.lineLimit(3)
}


}
.padding()
.frame(width: 80, height: geometry.size.height)
Expand Down
20 changes: 0 additions & 20 deletions Sources/SwipeableView/View/SwiftUIView.swift

This file was deleted.

67 changes: 37 additions & 30 deletions Sources/SwipeableView/View/SwipeableView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// SwipeableView.swift
// SwipeableView
//
//
// Created by Ilya on 10.10.20.
//
Expand All @@ -14,23 +14,25 @@ public enum ViewState: CaseIterable {
}

public struct SwipeableView<Content: View>: View {

@Environment(\.colorScheme) var colorScheme
@State var dragOffset: CGSize = .zero
@State private var state: ViewState = .center

var rounded: Bool
var leftActions: EditActionsVM
var rightActions: EditActionsVM
@ObservedObject var viewModel: SWViewModel

let content: Content

public init(@ViewBuilder content: () -> Content, leftActions: [Action], rightActions: [Action], rounded: Bool = false) {
public init(@ViewBuilder content: () -> Content, leftActions: [Action], rightActions: [Action], rounded: Bool = false, container: SwManager? = nil ) {

self.content = content()
self.leftActions = EditActionsVM(leftActions, maxActions: leftActions.count)
self.rightActions = EditActionsVM(rightActions, maxActions: rightActions.count)
self.rounded = rounded
self.dragOffset = .zero

viewModel = SWViewModel(state: .center, size: .zero)
container?.addView(viewModel)

}

private func makeView(_ geometry: GeometryProxy) -> some View {
Expand All @@ -40,12 +42,23 @@ public struct SwipeableView<Content: View>: View {
public var body: some View {

ZStack {
switch state {

switch viewModel.state {
case .left:
EditActions(viewModel: leftActions, offset: $dragOffset, state: $state, side: .left, rounded: rounded)

EditActions(viewModel: leftActions,
offset: .init(get: {viewModel.dragOffset}, set: {viewModel.dragOffset = $0}),
state: .init(get: {viewModel.state}, set: {viewModel.state = $0}),
side: .left,
rounded: rounded)

case .right :
EditActions(viewModel: rightActions, offset: $dragOffset, state: $state, side: .right, rounded: rounded)

EditActions(viewModel: rightActions,
offset: .init(get: {viewModel.dragOffset}, set: {viewModel.dragOffset = $0}),
state: .init(get: {viewModel.state}, set: {viewModel.state = $0}),
side: .right,
rounded: rounded)
case .center:
EmptyView()

Expand All @@ -54,12 +67,12 @@ public struct SwipeableView<Content: View>: View {
GeometryReader { reader in
self.makeView(reader)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.offset(x: dragOffset.width)
.offset(x: viewModel.dragOffset.width)
}
.onTapGesture(count: /*@START_MENU_TOKEN@*/1/*@END_MENU_TOKEN@*/, perform: {
.onTapGesture(count: 1, perform: {
withAnimation {
dragOffset = CGSize.zero
state = .center
viewModel.dragOffset = CGSize.zero
viewModel.state = .center
}
})

Expand All @@ -70,39 +83,39 @@ public struct SwipeableView<Content: View>: View {
withAnimation {

#if DEBUG
print(dragOffset)
print(viewModel.dragOffset)
#endif

if value.translation.width < 0 && value.translation.height > -30 && value.translation.height < 30 {
// left
if state == .center {
if viewModel.state == .center {
var offset = (CGFloat(min(4, leftActions.actions.count)) * -80)
if rounded {
offset -= CGFloat(min(4, leftActions.actions.count)) * 5
}

dragOffset = (CGSize.init(width: offset, height: 0))
state = .left
viewModel.dragOffset = CGSize.init(width: offset, height: 0)
viewModel.state = .left
} else {
dragOffset = CGSize.zero
state = .center
viewModel.dragOffset = CGSize.zero
viewModel.state = .center
}


} else if value.translation.width > 0 && value.translation.height > -30 && value.translation.height < 30 {
// right
if state == .center {
if viewModel.state == .center {

var offset = (CGFloat(min(4, rightActions.actions.count)) * +80)
if rounded {
offset += CGFloat(min(4, rightActions.actions.count)) * 5
}

dragOffset = (CGSize.init(width: offset, height: 0))
state = .right
viewModel.dragOffset = (CGSize.init(width: offset, height: 0))
viewModel.state = .right
} else {
dragOffset = CGSize.zero
state = .center
viewModel.dragOffset = CGSize.zero
viewModel.state = .center
}

}
Expand All @@ -113,12 +126,6 @@ public struct SwipeableView<Content: View>: View {
}
}

class example: SwipeableViewModel {
@Published var leftActions: EditActionsVM = EditActionsVM([], maxActions: 4)
@Published var rightActions: EditActionsVM = EditActionsVM([], maxActions: 4)
@Published var dragOffset: CGSize = CGSize.zero

}
@available(iOS 14.0, *)
struct SwipebleView_Previews: PreviewProvider {
static var previews: some View {
Expand Down
37 changes: 37 additions & 0 deletions Sources/SwipeableView/ViewModel/SWViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// File.swift
//
//
// Created by Ilya on 14.10.20.
//

import Combine
import SwiftUI

public class SWViewModel: ObservableObject {
let id: UUID = UUID.init()
@Published var state: ViewState {
didSet {
if state != .center {
self.stateDidChange.send(self)
}
}
}

@Published var dragOffset: CGSize
let stateDidChange = PassthroughSubject<SWViewModel, Never>()

init(state: ViewState, size: CGSize) {
self.state = state
self.dragOffset = size
}

public func goToCenter(){
DispatchQueue.main.async {
withAnimation {
self.state = .center
self.dragOffset = .zero
}
}
}
}
40 changes: 40 additions & 0 deletions Sources/SwipeableView/ViewModel/SwManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// SwManager.swift
//
//
// Created by Ilya on 14.10.20.
//

import Combine

public class SwManager: ObservableObject {
private var views: [SWViewModel]
private var subscriptions = Set<AnyCancellable>()

public init() {
views = []
}

public func hideAllViews() {
self.views.forEach {
$0.goToCenter()
}
}

public func addView(_ view: SWViewModel) {
views.append(view)

view.stateDidChange.sink(receiveValue: { vm in
if self.views.count != 0 {
#if DEBUG
print("swiped = \(vm.id.uuidString)")
#endif
self.views.forEach {
if vm.id != $0.id && $0.state != .center{
$0.goToCenter()
}
}
}
}).store(in: &subscriptions)
}
}
16 changes: 0 additions & 16 deletions Sources/SwipeableView/ViewModel/SwipeableViewModel.swift

This file was deleted.

0 comments on commit 7ea14f0

Please sign in to comment.