-
Notifications
You must be signed in to change notification settings - Fork 170
Add Animation Completion Parameter #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
359ba84
790668e
efd5d00
c0a1f04
320dfa3
0d9d7a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,35 +64,45 @@ 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. | ||
| /// | ||
| /// 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. | ||
| /// | ||
| /// 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. | ||
| /// | ||
| /// 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) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please wrap these function signatures on to multiple lines
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i broke the line of function name that longer then 110 characters.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. however, here is my break line style. if you don't like this style please commit the additional feedback. i will apply as soon as possible. |
||
| 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. | ||
| /// | ||
| /// 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, | ||
|
|
@@ -102,20 +112,30 @@ 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. | ||
| /// | ||
| /// 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. | ||
| /// | ||
| /// 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, | ||
|
|
@@ -125,44 +145,55 @@ 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. | ||
| /// | ||
| /// 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. | ||
| /// | ||
| /// 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) | ||
| } | ||
| } | ||
|
|
||
| /// 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 | ||
|
|
@@ -205,53 +236,68 @@ 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. | ||
| /// | ||
| /// 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. | ||
| /// | ||
| /// 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. | ||
| /// | ||
| /// 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`. | ||
| /// | ||
| /// 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() | ||
| } | ||
| }, completion: completion) | ||
| } else { | ||
| cell.isHidden = isHidden | ||
| completion?(true) | ||
| } | ||
| } | ||
|
|
||
| /// Hides the given rows if `isHidden` is `true`, or shows the given rows if `isHidden` is | ||
| /// `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. | ||
|
|
@@ -529,7 +575,10 @@ 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) | ||
|
|
@@ -551,16 +600,18 @@ open class AloeStackView: UIScrollView { | |
| if animated { | ||
| cell.alpha = 0 | ||
| layoutIfNeeded() | ||
| UIView.animate(withDuration: 0.3) { | ||
| UIView.animate(withDuration: 0.3, animations: { | ||
| cell.alpha = 1 | ||
| } | ||
| }, completion: completion) | ||
| } 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 completionHandler: (Bool) -> Void = { [weak self] finished in | ||
| guard let `self` = self else { return } | ||
| cell.removeFromSuperview() | ||
|
|
||
|
|
@@ -569,17 +620,16 @@ open class AloeStackView: UIScrollView { | |
| if let aboveCell = aboveCell { | ||
| self.updateSeparatorVisibility(forCell: aboveCell) | ||
| } | ||
|
|
||
| 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) | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the parameter should start on the next line:
if you could apply this style to the other callsites that would be great!