[iOS]UItableViewの順序を変更する-UItableViewReorderControl
発端
上記の設計の順序を変更するためにUIを作成する必要があります.
まず大体の方法は頭の中で見つけましたが、
第一の方法
MelonやYouTube音楽などの音楽アプリやその他の各種アプリで使用される手順変更方法.個別の編集ボタンがあるため、通常はビューモードと編集モードを個別に使用する場合に使用されます.
第2の方法
長時間クリックしてドラッグして移動する方法
登録
選択!
元々の企画では団地全体が少し触れても移動できるようにすることを意図していましたが、1つ目の方法の使用性も良かったので、1つ目の方法を採用することにしました.実際にcellを全域に設定することも不可能ではありませんが、一般的にはあまり一般的な方法ではなく、あまり参考にならないので一時的に延期しました.
遅延の過程で、reorder control画像をカスタマイズするために、グーグルが検索したところ、対応する実現方法が発見された.でも….実機でテストしたところ、スクロールしようとしたが、セルを移動したが、セルをスクロールした場合があったので使用しないことにした.この方法も以下でまとめます.
展開:reorder control imagecustom
まず、大きな構造はappbar、tableView、底部のButton View(このうち2つのビュー)なので、ボタンビューを溝領域に伸ばしやすくしたいと思います.
方法編集=true/moveRowAt設定
class ViewController: UIViewController {
private var snsd = [
["태연", "890309"],
["써니", "890515"],
["티파니", "890801"],
["효연", "890922"],
["유리", "891205"],
["수영", "900210"],
["윤아", "900530"],
["서현", "910628"],
]
// 이 안에 있는 설정은 대체로 viewDidLoad 에서 하지만 개인적으로 closure 를 이용해서 생성하는걸 더 좋아해서 이렇게 했다!
private lazy var tableView: UITableView = {
let v = UITableView()
let snsdCell = UINib(nibName: "SnsdTableViewCell", bundle: nil)
v.register(snsdCell, forCellReuseIdentifier: "SnsdCell")
v.isEditing = true // isEditing 설정!!!
v.dataSource = self
v.delegate = self
return v
}()
private let btn: UIButton = {
let btn = UIButton()
btn.setTitle("적용하기", for: .normal)
btn.backgroundColor = .orange
btn.addTarget(self, action: #selector(btnPressed), for: .touchUpInside)
btn.contentEdgeInsets = UIEdgeInsets(top: -20, left: 0, bottom: 0, right: 0)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(tableView)
view.addSubview(btn)
tableView.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
make.left.right.equalToSuperview()
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-50)
}
btn.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-50)
make.left.right.bottom.equalToSuperview()
}
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return snsd.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SnsdCell", for: indexPath) as! SnsdTableViewCell
cell.nameLabel.text = snsd[indexPath.row][0]
cell.birthLabel.text = snsd[indexPath.row][1]
return cell
}
// 왼쪽 버튼 없애기
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
// editing = true 일 때 왼쪽 버튼이 나오기 위해 들어오는 indent 없애기
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
// 오른쪽 reorder control 이 나오면서 셀을 이동할 수 있게 됨.
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let removed = snsd.remove(at: sourceIndexPath.row)
snsd.insert(removed, at: destinationIndexPath.row)
}
}
結果
ただ….横から出る本来はデザインの方法があるのですが、どんな方法を使っても右側からreorder controlが出てくるviewは同じで、他の大企業アプリケーションでもフレームを使ったデザインはほとんどないので、フレームを外しました.やれやれ!
方法EditingAccessyViewじゃないの?
結論から言うと、そうではありません.
// ViewController > cellForRowAt
// customCell 클래스의 awakeFromNib 이나 init 에서 해줘도 같다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SnsdCell", for: indexPath) as! SnsdTableViewCell
cell.nameLabel.text = snsd[indexPath.row][0]
cell.birthLabel.text = snsd[indexPath.row][1]
cell.editingAccessoryView = UIImageView(image: UIImage(named: "reorder"))
return cell
}
結果
それとも...ただreorder controlの隣にAccessory Viewが現れた...だからまず携帯のハンバーガーボタンviewを外したいと思います.
方法WillDisplay(またはセルのsetEditing)でUItableViewの画像ビューを変更する
ソース-https://pilvi.tistory.com/2?category=868530
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// cell 의 subview 에서 UITableViewReorderControl 안의
// imageView 를 찾아와서
let imageView = cell.subviews.first(where: { $0.description.contains("Reorder") })?.subviews.first(where: { $0 is UIImageView }) as? UIImageView
// image 변경
imageView?.image = UIImage(named: "reorder")
// imageView 의 frame 변경
let size: CGFloat = 20
imageView?.frame.size.width = size
imageView?.frame.size.height = size
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
for view in cell.subviews {
if view.self.description.contains("UITableViewCellReorderControl") {
for sv in view.subviews {
if (sv is UIImageView) {
(sv as? UIImageView)?.image = UIImage(named: "reorder")
(sv as? UIImageView)?.contentMode = .center
sv.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
}
}
}
}
}
// willDisplay 안에서 cell 안의 subview 를 찾는 것과 같은 효과.
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
if editing {
for view in subviews where view.description.contains("Reorder") {
for case let subview as UIImageView in view.subviews {
subview.image = UIImage(named: "reorder")
subview.frmae = CGRect(x: 0, y: 0, width: 20, height: 20)
}
}
}
}
結果
変更後のreorder画像を適用しましたが...順番を変えようとした瞬間、基本イメージに戻った.上のコードは一定の割合を保っていますが...でもイメージを変えるのも同じです.また、画像は目的の正しい位置に置かれているわけではありません.
2つのコードは異なるが、意味は同じだが、イメージを変えて比率を維持する理由も興味深い.
クライシス:reorderイメージ""位置""custom"
方法以上の方法のイメージです。frame.origin.位置をxに変更
ソース-https://tutorialmeta.com/question/change-reorder-controls-color-in-table-view-cell-for-ios-15
private myReorderImage: UIImage?
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
for subView in cell.subviews {
if (subView.classForCoder.description() == "UITableViewCellReorderControl") {
for sv in subView.subviews {
if (sv.isKind(of: UIImageView.classForCoder())) {
// 위처럼 이미지를 수정하는게 아니라 그냥 원래 이미지를 아예 없애버리고
sv.removeFromSuperview()
let imageView = UIImageView()
if (self.myReorderImage == nil) {
let myImage = imageView.image
myReorderImage = myImage?.withRenderingMode(.alwaysTemplate)
}
// 새로운 이미지로 세팅!
var frame = imageView.frame
frame.origin.x = -10
frame.origin.y = 20
frame.size = CGSize(width: 24, height: 24)
self.myReorderImage = UIImage(named: "reorder") // set your image
imageView.frame = frame
imageView.image = self.myReorderImage
subView.addSubview(imageView) // add imageView to reorder control
break
}
}
break
}
}
}
しかしこのコードにも問題があります...クリックすると、画像が変わります.frame.画像を原点に移動して0以下にすると、画像は所望の位置に…並べ替え制御の範囲を超えた箇所が出てきましたが、その部分で制御しようとすると制御できなくなります…ここまで来るとデザイン通りに合わなくなり、一度デザインを変えたことがありますが...ここまで来ればなんとかなると思い、Google(Google)を再開しました.
クライマックス:reorder control領域のセル全体を展開し、非表示=元の意図で操作されたコードを検索します。
方法並べ替え制御をセル全体に拡張
ソース-http://jike.in/?qa=816545/ios-reordering-uitableview-without-reorder-control
このコードは上のwillDisplayコードをsetEditingに入れてcellにインポートします!そこで制御を並べ替える
weak var reorderControl: UIView?
override func layoutSubviews() {
super.layoutSubviews()
// Make the cell's `contentView` as big as the entire cell.
contentView.frame = bounds
// Make the reorder control as big as the entire cell
// so you can drag from everywhere inside the cell.
reorderControl?.frame = bounds
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: false)
if !editing || reorderControl != nil {
return
}
// Find the reorder control in the cell's subviews.
for view in subviews {
let className = String(describing: type(of:view))
if className == "UITableViewCellReorderControl" {
// Remove its subviews so that they don't mess up
// your own content's appearance.
for subview in view.subviews {
subview.removeFromSuperview()
}
// Keep a weak reference to it for `layoutSubviews()`.
reorderControl = view
break
}
}
}
ReorderControlのフレームワークを変更します.しかし、cellの高さが正しくないと、table viewを転がすとcellが消えてしまう・・・注意...tableView.rowHeight = 72
はそうです結果
初めてプールを移動した時以外は、転がりたいです.cellがずっと動いている様子...
結果:ん?最後の2つが混ざったら…?
方法本当の最後
// reorder control custom
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
for subView in cell.subviews {
if (subView.classForCoder.description() == "UITableViewCellReorderControl") {
// reorder control frame 을 변경해서 세부적인 위치를 맞춰준다. - 오른쪽 간격 맞추기 위해서
let reorderControl = subView
let frame = reorderControl.frame
reorderControl.frame = CGRect(x: self.view.frame.width - 56, y: frame.minY, width: frame.width, height: frame.height)
for subViewB in reorderControl.subviews {
if (subViewB.isKind(of: UIImageView.classForCoder())) {
// reorder control default image 제거
subViewB.removeFromSuperview()
let imageView = UIImageView()
if (self.myReorderImage == nil) {
let myImage = imageView.image
myReorderImage = myImage?.withRenderingMode(.alwaysTemplate)
}
// reorder control image 변경
var frame = imageView.frame
frame.origin.x = 0
frame.origin.y = 24
frame.size = CGSize(width: 20, height: 20)
self.myReorderImage = UIImage(named: "reorder") // set your image
imageView.frame = frame
imageView.image = self.myReorderImage
reorderControl.addSubview(imageView) // add imageView to reorder control
break
}
}
break
}
}
}
完成!!!
まったく.最初は福贴りを贴りたいだけで勝手に使えないなら他のものを探して...混ざった感じでいいので和音が難しくない和音を理解してみてください
画像ソース-https://docs.microsoft.com/en-us/dotnet/api/uikit.uitableviewcell?view=xamarin-ios-sdk-12
この画像からcellのサブビューにはreorder controlがあり、imageがあることがわかります.私たちはコードを利用してそれを見つけて修正しました!!
Reference
この問題について([iOS]UItableViewの順序を変更する-UItableViewReorderControl), 我々は、より多くの情報をここで見つけました https://velog.io/@ddosang/iOS-UITableView-순서-변경-UITableViewReorderControlテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol