From 359ba8404627af28298facd0d8ff136bcdcd9cd2 Mon Sep 17 00:00:00 2001 From: blick-9 Date: Fri, 5 Jul 2019 17:03:00 +0900 Subject: [PATCH 1/3] Added animation completion parameter to functions that singular animate operation --- Sources/AloeStackView/AloeStackView.swift | 48 +++++++++++++---------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/Sources/AloeStackView/AloeStackView.swift b/Sources/AloeStackView/AloeStackView.swift index 284ed2d..793c4cf 100644 --- a/Sources/AloeStackView/AloeStackView.swift +++ b/Sources/AloeStackView/AloeStackView.swift @@ -40,8 +40,8 @@ open class AloeStackView: UIScrollView { /// Adds a row to the end of the stack view. /// /// If `animated` is `true`, the insertion is animated. - open func addRow(_ row: UIView, animated: Bool = false) { - insertCell(withContentView: row, atIndex: stackView.arrangedSubviews.count, animated: animated) + open func addRow(_ row: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + insertCell(withContentView: row, atIndex: stackView.arrangedSubviews.count, animated: animated, completion: completion) } /// Adds multiple rows to the end of the stack view. @@ -54,8 +54,8 @@ open class AloeStackView: UIScrollView { /// Adds a row to the beginning of the stack view. /// /// If `animated` is `true`, the insertion is animated. - open func prependRow(_ row: UIView, animated: Bool = false) { - insertCell(withContentView: row, atIndex: 0, animated: animated) + open func prependRow(_ row: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + insertCell(withContentView: row, atIndex: 0, animated: animated, completion: completion) } /// Adds multiple rows to the beginning of the stack view. @@ -68,7 +68,7 @@ open class AloeStackView: UIScrollView { /// Inserts a row above the specified row in the stack view. /// /// If `animated` is `true`, the insertion is animated. - open func insertRow(_ row: UIView, before beforeRow: UIView, animated: Bool = false) { + open func insertRow(_ row: UIView, before beforeRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { #if swift(>=5.0) guard let cell = beforeRow.superview as? StackViewCell, @@ -78,7 +78,7 @@ open class AloeStackView: UIScrollView { let cell = beforeRow.superview as? StackViewCell, let index = stackView.arrangedSubviews.index(of: cell) else { return } #endif - insertCell(withContentView: row, atIndex: index, animated: animated) + insertCell(withContentView: row, atIndex: index, animated: animated, completion: completion) } /// Inserts multiple rows above the specified row in the stack view. @@ -91,7 +91,7 @@ open class AloeStackView: UIScrollView { /// Inserts a row below the specified row in the stack view. /// /// If `animated` is `true`, the insertion is animated. - open func insertRow(_ row: UIView, after afterRow: UIView, animated: Bool = false) { + open func insertRow(_ row: UIView, after afterRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { #if swift(>=5.0) guard let cell = afterRow.superview as? StackViewCell, @@ -101,7 +101,7 @@ open class AloeStackView: UIScrollView { let cell = afterRow.superview as? StackViewCell, let index = stackView.arrangedSubviews.index(of: cell) else { return } #endif - insertCell(withContentView: row, atIndex: index + 1, animated: animated) + insertCell(withContentView: row, atIndex: index + 1, animated: animated, completion: completion) } /// Inserts multiple rows below the specified row in the stack view. @@ -117,9 +117,9 @@ open class AloeStackView: UIScrollView { /// Removes the given row from the stack view. /// /// If `animated` is `true`, the removal is animated. - open func removeRow(_ row: UIView, animated: Bool = false) { + open func removeRow(_ row: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { if let cell = row.superview as? StackViewCell { - removeCell(cell, animated: animated) + removeCell(cell, animated: animated, completion: completion) } } @@ -181,8 +181,8 @@ open class AloeStackView: UIScrollView { /// Hides the given row, making it invisible. /// /// If `animated` is `true`, the change is animated. - open func hideRow(_ row: UIView, animated: Bool = false) { - setRowHidden(row, isHidden: true, animated: animated) + open func hideRow(_ row: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + setRowHidden(row, isHidden: true, animated: animated, completion: completion) } /// Hides the given rows, making them invisible. @@ -195,8 +195,8 @@ open class AloeStackView: UIScrollView { /// Shows the given row, making it visible. /// /// If `animated` is `true`, the change is animated. - open func showRow(_ row: UIView, animated: Bool = false) { - setRowHidden(row, isHidden: false, animated: animated) + open func showRow(_ row: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + setRowHidden(row, isHidden: false, animated: animated, completion: completion) } /// Shows the given rows, making them visible. @@ -209,16 +209,19 @@ open class AloeStackView: UIScrollView { /// Hides the given row if `isHidden` is `true`, or shows the given row if `isHidden` is `false`. /// /// If `animated` is `true`, the change is animated. - open func setRowHidden(_ row: UIView, isHidden: Bool, animated: Bool = false) { + open func setRowHidden(_ row: UIView, isHidden: Bool, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { guard let cell = row.superview as? StackViewCell, cell.isHidden != isHidden else { return } if animated { - UIView.animate(withDuration: 0.3) { + UIView.animate(withDuration: 0.3, animations: { cell.isHidden = isHidden cell.layoutIfNeeded() + }) { flag in + completion?(flag) } } else { cell.isHidden = isHidden + completion?(true) } } @@ -480,7 +483,7 @@ open class AloeStackView: UIScrollView { return cell } - private func insertCell(withContentView contentView: UIView, atIndex index: Int, animated: Bool) { + private func insertCell(withContentView contentView: UIView, atIndex index: Int, animated: Bool, completion: ((Bool) -> Void)? = nil) { let cellToRemove = containsRow(contentView) ? contentView.superview : nil let cell = createCell(withContentView: contentView) @@ -502,16 +505,20 @@ open class AloeStackView: UIScrollView { if animated { cell.alpha = 0 layoutIfNeeded() - UIView.animate(withDuration: 0.3) { + UIView.animate(withDuration: 0.3, animations: { cell.alpha = 1 + }) { flag in + completion?(flag) } + } else { + completion?(true) } } - private func removeCell(_ cell: StackViewCell, animated: Bool) { + private func removeCell(_ cell: StackViewCell, animated: Bool, completion: ((Bool) -> Void)? = nil) { let aboveCell = cellAbove(cell: cell) - let completion: (Bool) -> Void = { [weak self] _ in + let completion: (Bool) -> Void = { [weak self] flag in guard let `self` = self else { return } cell.removeFromSuperview() @@ -520,6 +527,7 @@ open class AloeStackView: UIScrollView { if let aboveCell = aboveCell { self.updateSeparatorVisibility(forCell: aboveCell) } + completion?(flag) } if animated { From 790668eda33f784f01bd0dfd07f5496ca82c01cb Mon Sep 17 00:00:00 2001 From: blick-9 Date: Fri, 5 Jul 2019 17:23:42 +0900 Subject: [PATCH 2/3] Added animation completion parameter to functions that plural animate operation --- Sources/AloeStackView/AloeStackView.swift | 56 +++++++++++++++-------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/Sources/AloeStackView/AloeStackView.swift b/Sources/AloeStackView/AloeStackView.swift index 793c4cf..1c21e5d 100644 --- a/Sources/AloeStackView/AloeStackView.swift +++ b/Sources/AloeStackView/AloeStackView.swift @@ -47,8 +47,10 @@ open class AloeStackView: UIScrollView { /// Adds multiple rows to the end of the stack view. /// /// If `animated` is `true`, the insertions are animated. - open func addRows(_ rows: [UIView], animated: Bool = false) { - rows.forEach { addRow($0, animated: animated) } + open func addRows(_ rows: [UIView], animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.forEach { group.enter(); addRow($0, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Adds a row to the beginning of the stack view. @@ -61,8 +63,10 @@ open class AloeStackView: UIScrollView { /// Adds multiple rows to the beginning of the stack view. /// /// If `animated` is `true`, the insertions are animated. - open func prependRows(_ rows: [UIView], animated: Bool = false) { - rows.reversed().forEach { prependRow($0, animated: animated) } + open func prependRows(_ rows: [UIView], animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.reversed().forEach { group.enter(); prependRow($0, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Inserts a row above the specified row in the stack view. @@ -84,8 +88,10 @@ open class AloeStackView: UIScrollView { /// Inserts multiple rows above the specified row in the stack view. /// /// If `animated` is `true`, the insertions are animated. - open func insertRows(_ rows: [UIView], before beforeRow: UIView, animated: Bool = false) { - rows.forEach { insertRow($0, before: beforeRow, animated: animated) } + open func insertRows(_ rows: [UIView], before beforeRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.forEach { group.enter(); insertRow($0, before: beforeRow, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Inserts a row below the specified row in the stack view. @@ -107,11 +113,14 @@ open class AloeStackView: UIScrollView { /// Inserts multiple rows below the specified row in the stack view. /// /// If `animated` is `true`, the insertions are animated. - open func insertRows(_ rows: [UIView], after afterRow: UIView, animated: Bool = false) { + open func insertRows(_ rows: [UIView], after afterRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() _ = rows.reduce(afterRow) { currentAfterRow, row in - insertRow(row, after: currentAfterRow, animated: animated) + group.enter() + insertRow(row, after: currentAfterRow, animated: animated) { _ in group.leave() } return row } + group.notify(queue: .main) { completion?(true) } } /// Removes the given row from the stack view. @@ -126,19 +135,24 @@ open class AloeStackView: UIScrollView { /// Removes the given rows from the stack view. /// /// If `animated` is `true`, the removals are animated. - open func removeRows(_ rows: [UIView], animated: Bool = false) { - rows.forEach { removeRow($0, animated: animated) } + open func removeRows(_ rows: [UIView], animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.forEach { group.enter(); removeRow($0, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Removes all the rows in the stack view. /// /// If `animated` is `true`, the removals are animated. - open func removeAllRows(animated: Bool = false) { + open func removeAllRows(animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() stackView.arrangedSubviews.forEach { view in if let cell = view as? StackViewCell { - removeRow(cell.contentView, animated: animated) + group.enter() + removeRow(cell.contentView, animated: animated) { _ in group.leave() } } } + group.notify(queue: .main) { completion?(true) } } // MARK: Accessing Rows @@ -188,8 +202,10 @@ open class AloeStackView: UIScrollView { /// Hides the given rows, making them invisible. /// /// If `animated` is `true`, the changes are animated. - open func hideRows(_ rows: [UIView], animated: Bool = false) { - rows.forEach { hideRow($0, animated: animated) } + open func hideRows(_ rows: [UIView], animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.forEach { group.enter(); hideRow($0, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Shows the given row, making it visible. @@ -202,8 +218,10 @@ open class AloeStackView: UIScrollView { /// Shows the given rows, making them visible. /// /// If `animated` is `true`, the changes are animated. - open func showRows(_ rows: [UIView], animated: Bool = false) { - rows.forEach { showRow($0, animated: animated) } + open func showRows(_ rows: [UIView], animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.forEach { group.enter(); showRow($0, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Hides the given row if `isHidden` is `true`, or shows the given row if `isHidden` is `false`. @@ -229,8 +247,10 @@ open class AloeStackView: UIScrollView { /// `false`. /// /// If `animated` is `true`, the change are animated. - open func setRowsHidden(_ rows: [UIView], isHidden: Bool, animated: Bool = false) { - rows.forEach { setRowHidden($0, isHidden: isHidden, animated: animated) } + open func setRowsHidden(_ rows: [UIView], isHidden: Bool, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + let group = DispatchGroup() + rows.forEach { group.enter(); setRowHidden($0, isHidden: isHidden, animated: animated) { _ in group.leave() } } + group.notify(queue: .main) { completion?(true) } } /// Returns `true` if the given row is hidden, `false` otherwise. From 320dfa3d4a2af1b701650cf6026e30f30f276176 Mon Sep 17 00:00:00 2001 From: blick-9 Date: Fri, 16 Aug 2019 14:43:19 +0900 Subject: [PATCH 3/3] Apply pull request feedbacks - insert blank line - change argument, variable name - truncate line what function name that parameters length longer than 110 characters --- Sources/AloeStackView/AloeStackView.swift | 72 +++++++++++++++-------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/Sources/AloeStackView/AloeStackView.swift b/Sources/AloeStackView/AloeStackView.swift index 16f1215..7ce4830 100644 --- a/Sources/AloeStackView/AloeStackView.swift +++ b/Sources/AloeStackView/AloeStackView.swift @@ -65,7 +65,10 @@ open class AloeStackView: UIScrollView { /// /// If `animated` is `true`, the insertion is animated. open func addRow(_ row: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { - insertCell(withContentView: row, atIndex: stackView.arrangedSubviews.count, animated: animated, completion: completion) + insertCell(withContentView: row, + atIndex: stackView.arrangedSubviews.count, + animated: animated, + completion: completion) } /// Adds multiple rows to the end of the stack view. @@ -96,7 +99,10 @@ open class AloeStackView: UIScrollView { /// Inserts a row above the specified row in the stack view. /// /// If `animated` is `true`, the insertion is animated. - open func insertRow(_ row: UIView, before beforeRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + open func insertRow(_ row: UIView, + before beforeRow: UIView, + animated: Bool = false, + completion: ((Bool) -> Void)? = nil) { #if swift(>=5.0) guard let cell = beforeRow.superview as? StackViewCell, @@ -112,16 +118,24 @@ open class AloeStackView: UIScrollView { /// Inserts multiple rows above the specified row in the stack view. /// /// If `animated` is `true`, the insertions are animated. - open func insertRows(_ rows: [UIView], before beforeRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + open func insertRows(_ rows: [UIView], + before beforeRow: UIView, + animated: Bool = false, + completion: ((Bool) -> Void)? = nil) { let group = DispatchGroup() - rows.forEach { group.enter(); insertRow($0, before: beforeRow, animated: animated) { _ in group.leave() } } + rows.forEach { + group.enter() + insertRow($0, before: beforeRow, animated: animated) { _ in group.leave() } } group.notify(queue: .main) { completion?(true) } } /// Inserts a row below the specified row in the stack view. /// /// If `animated` is `true`, the insertion is animated. - open func insertRow(_ row: UIView, after afterRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + open func insertRow(_ row: UIView, + after afterRow: UIView, + animated: Bool = false, + completion: ((Bool) -> Void)? = nil) { #if swift(>=5.0) guard let cell = afterRow.superview as? StackViewCell, @@ -137,7 +151,10 @@ open class AloeStackView: UIScrollView { /// Inserts multiple rows below the specified row in the stack view. /// /// If `animated` is `true`, the insertions are animated. - open func insertRows(_ rows: [UIView], after afterRow: UIView, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + open func insertRows(_ rows: [UIView], + after afterRow: UIView, + animated: Bool = false, + completion: ((Bool) -> Void)? = nil) { let group = DispatchGroup() _ = rows.reduce(afterRow) { currentAfterRow, row in group.enter() @@ -251,16 +268,17 @@ open class AloeStackView: UIScrollView { /// Hides the given row if `isHidden` is `true`, or shows the given row if `isHidden` is `false`. /// /// If `animated` is `true`, the change is animated. - open func setRowHidden(_ row: UIView, isHidden: Bool, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + open func setRowHidden(_ row: UIView, + isHidden: Bool, + animated: Bool = false, + completion: ((Bool) -> Void)? = nil) { guard let cell = row.superview as? StackViewCell, cell.isHidden != isHidden else { return } if animated { UIView.animate(withDuration: 0.3, animations: { cell.isHidden = isHidden cell.layoutIfNeeded() - }) { flag in - completion?(flag) - } + }, completion: completion) } else { cell.isHidden = isHidden completion?(true) @@ -271,9 +289,14 @@ open class AloeStackView: UIScrollView { /// `false`. /// /// If `animated` is `true`, the change are animated. - open func setRowsHidden(_ rows: [UIView], isHidden: Bool, animated: Bool = false, completion: ((Bool) -> Void)? = nil) { + open func setRowsHidden(_ rows: [UIView], + isHidden: Bool, + animated: Bool = false, + completion: ((Bool) -> Void)? = nil) { let group = DispatchGroup() - rows.forEach { group.enter(); setRowHidden($0, isHidden: isHidden, animated: animated) { _ in group.leave() } } + rows.forEach { + group.enter() + setRowHidden($0, isHidden: isHidden, animated: animated) { _ in group.leave() } } group.notify(queue: .main) { completion?(true) } } @@ -552,7 +575,10 @@ open class AloeStackView: UIScrollView { return cell } - private func insertCell(withContentView contentView: UIView, atIndex index: Int, animated: Bool, completion: ((Bool) -> Void)? = nil) { + private func insertCell(withContentView contentView: UIView, + atIndex index: Int, + animated: Bool, + completion: ((Bool) -> Void)? = nil) { let cellToRemove = containsRow(contentView) ? contentView.superview : nil let cell = createCell(withContentView: contentView) @@ -576,9 +602,7 @@ open class AloeStackView: UIScrollView { layoutIfNeeded() UIView.animate(withDuration: 0.3, animations: { cell.alpha = 1 - }) { flag in - completion?(flag) - } + }, completion: completion) } else { completion?(true) } @@ -587,7 +611,7 @@ open class AloeStackView: UIScrollView { private func removeCell(_ cell: StackViewCell, animated: Bool, completion: ((Bool) -> Void)? = nil) { let aboveCell = cellAbove(cell: cell) - let completion: (Bool) -> Void = { [weak self] flag in + let completionHandler: (Bool) -> Void = { [weak self] finished in guard let `self` = self else { return } cell.removeFromSuperview() @@ -596,18 +620,16 @@ open class AloeStackView: UIScrollView { if let aboveCell = aboveCell { self.updateSeparatorVisibility(forCell: aboveCell) } - completion?(flag) + + completion?(finished) } if animated { - UIView.animate( - withDuration: 0.3, - animations: { - cell.isHidden = true - }, - completion: completion) + UIView.animate(withDuration: 0.3, animations: { + cell.isHidden = true + }, completion: completionHandler) } else { - completion(true) + completionHandler(true) } }