SwiftUI表自定义滑动?

时间:2019-06-26 18:46:04

标签: swift swiftui

有没有一种方法可以左右滑动表行?我还没有为新的Framework SwiftUI找到任何东西,所以也许没有机会为此使用SwiftUI?我需要删除行并使用自定义滑动键

2 个答案:

答案 0 :(得分:0)

可以很简单地执行删除动作和重新排序列表项的功能。

(function() {
  'use strict';

  angular
    .module('ShoppingListCheckOff', [])
    .controller('ToBuyController', ToBuyController)
    .controller('AlreadyBoughtController', AlreadyBoughtController)
    .service('ShoppingListCheckOffService', ShoppingListCheckOffService);

  ToBuyController.$inject = ['ShoppingListCheckOffService'];
  function ToBuyController(ShoppingListCheckOffService) {
    var toBuy = this;

    toBuy.list = ShoppingListCheckOffService.getList(1);

    toBuy.bought = function(itemIndex) {
      ShoppingListCheckOffService.transfer(itemIndex);
    };
  }

  AlreadyBoughtController.$inject = ['ShoppingListCheckOffService'];
  function AlreadyBoughtController(ShoppingListCheckOffService) {
    var bought = this;

    bought.list = ShoppingListCheckOffService.getList(2);
  }
  function ShoppingListCheckOffService() {
    var service = this;

    // List of shopping items
    var list1 = [
      { name: 'Cookies', quantity: 10 },
      { name: 'Bananas', quantity: 100 },
      { name: 'Toys', quantity: 6 },
      { name: 'Dildos', quantity: 300 },
      { name: 'Yaakovs', quantity: 1 }
    ];

    var list2 = [];

    service.transfer = function(itemIndex) {
      list2 = list2.concat(list1.splice(itemIndex, 1));
      console.log('List 1', list1);
      console.log('List 2', list2);
    };

    service.getList = function(num) {
      if (num == 1) {
        return list1;
      }
      if (num == 2) {
        return list2;
      }
    };
  }
})();

编辑:苹果有这篇文章,我不敢相信我以前没有找到。 Composing SwiftUI Gestures。我还没有尝试过,但是这篇文章似乎做得很好!

答案 1 :(得分:0)

我想要同样的,现在有以下实现。

SwipeController 检查何时执行滑动操作并执行 SwipeAction,现在您可以在 executeAction 函数的打印行下添加滑动操作。但最好从这个做一个抽象类。

然后在 SwipeLeftRightContainer 结构中,我们拥有 DragGesture 中的大部分逻辑。它的作用是在您拖动时更改偏移量,然后调用 SwipeController 以查看是否达到了向左或向右滑动的阈值。然后当您完成拖动时,它将进入 DragGesture 的 onEnded 回调。这里我们将重置偏移量,让 SwipeController 决定执行一个动作。

请记住,视图中的许多变量对于 iPhone X 都是静态的,因此您应该将它们更改为最适合的变量。

import SwiftUI

/** executeRight: checks if it should execute the swipeRight action
    execute Left: checks if it should execute the swipeLeft action
    submitThreshold: the threshold of the x offset when it should start executing the action
*/
class SwipeController {
    var executeRight = false
    var executeLeft = false
    let submitThreshold: CGFloat = 200
    
    func checkExecutionRight(offsetX: CGFloat) {
        if offsetX > submitThreshold && self.executeRight == false {
            Utils.HapticSuccess()
            self.executeRight = true
        } else if offsetX < submitThreshold {
            self.executeRight = false
        }
    }
    
    func checkExecutionLeft(offsetX: CGFloat) {
        if offsetX < -submitThreshold && self.executeLeft == false {
            Utils.HapticSuccess()
            self.executeLeft = true
        } else if offsetX > -submitThreshold {
            self.executeLeft = false
        }
    }
    
    func excuteAction() {
        if executeRight {
            print("executed right")
        } else if executeLeft {
            print("executed left")
        }
        
        self.executeLeft = false
        self.executeRight = false
    }
}

struct SwipeLeftRightContainer: View {
    
    var swipeController: SwipeController = SwipeController()
    
    @State var offsetX: CGFloat = 0
    
    let maxWidth: CGFloat = 335
    let maxHeight: CGFloat = 125
    let swipeObjectsOffset: CGFloat = 350
    let swipeObjectsWidth: CGFloat = 400
    
    @State var rowAnimationOpacity: Double = 0
    var body: some View {
        ZStack {
            Group {
                HStack {
                    Text("Sample row")
                    Spacer()
                }
            }.padding(10)
            .zIndex(1.0)
            .frame(width: maxWidth, height: maxHeight)
            .cornerRadius(5)
            .background(RoundedRectangle(cornerRadius: 10).fill(Color.gray))
            .padding(10)
            .offset(x: offsetX)
            .gesture(DragGesture(minimumDistance: 5).onChanged { gesture in
                withAnimation(Animation.linear(duration: 0.1)) {
                    offsetX = gesture.translation.width
                }
                swipeController.checkExecutionLeft(offsetX: offsetX)
                swipeController.checkExecutionRight(offsetX: offsetX)
            }.onEnded { _ in
                withAnimation(Animation.linear(duration: 0.1)) {
                    offsetX = 0
                    swipeController.prevLocX = 0
                    swipeController.prevLocXDiff = 0
                    self.swipeController.excuteAction()
                }
            })
            Group {
                ZStack {
                    Rectangle().fill(Color.red).frame(width: swipeObjectsWidth, height: maxHeight).opacity(opacityDelete)
                    Image(systemName: "multiply").font(Font.system(size: 34)).foregroundColor(Color.white).padding(.trailing, 150)
                }
            }.zIndex(0.9).offset(x: swipeObjectsOffset + offsetX)
            Group {
                ZStack {
                    Rectangle().fill(Color.green).frame(width: swipeObjectsWidth, height: maxHeight).opacity(opacityLike)
                    Image(systemName: "heart").font(Font.system(size: 34)).foregroundColor(Color.white).padding(.leading, 150)
                }
            }.zIndex(0.9).offset(x: -swipeObjectsOffset + offsetX)
        }
    }
    
    var opacityDelete: Double {
        if offsetX < 0 {
            return Double(abs(offsetX) / 50)
        }
        return 0
    }
    
    var opacityLike: Double {
        if offsetX > 0 {
            return Double(offsetX / 50)
        }
        return 0
    }
}

struct SwipeListView: View {
    
    var body: some View {
        ScrollView {
            ForEach(0..<10) { index in
                SwipeLeftRightContainer().listRowInsets(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10))
            }
        }
    }
    
}

struct SwipeLeftRight_Previews: PreviewProvider {
    static var previews: some View {
        SwipeListView()
    }
}