Commit 11165627 by Daniel Dahan

development: fixed double hit test in Menu that was causing the delegation…

development: fixed double hit test in Menu that was causing the delegation method to be fired more than once
parent 8fbde3d6
{
"images" : [
{
"idiom" : "universal",
"filename" : "ic_work_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "ic_work_white@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "ic_work_white@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
......@@ -94,7 +94,6 @@ extension CollectionViewController {
}
extension CollectionViewController: CollectionViewDelegate {}
extension CollectionViewController: CollectionViewDataSource {
@objc
open func numberOfSections(in collectionView: UICollectionView) -> Int {
......
......@@ -95,6 +95,7 @@ public struct Icon {
public static let starHalf = Icon.icon("ic_star_half_white")
public static let videocam = Icon.icon("ic_videocam_white")
public static let visibility = Icon.icon("ic_visibility_white")
public static let work = Icon.icon("ic_work_white")
/// CosmicMind icons.
public struct cm {
......
......@@ -110,7 +110,7 @@ extension UIView {
}
}
/// Grid reference.
/// Depth reference.
open var depth: Depth {
get {
return layer.depth
......
......@@ -104,15 +104,7 @@ open class Menu: View {
open var itemSize = CGSize(width: 48, height: 48)
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
/**
Since the subviews will be outside the bounds of this view,
we need to look at the subviews to see if we have a hit.
*/
guard !isHidden else {
return nil
}
guard isOpened else {
guard isOpened, isEnabled else {
return super.hitTest(point, with: event)
}
......@@ -126,7 +118,7 @@ open class Menu: View {
delegate?.menu?(menu: self, tappedAt: point, isOutside: true)
return super.hitTest(point, with: event)
return self.hitTest(point, with: event)
}
/**
......@@ -150,10 +142,46 @@ open class Menu: View {
/// Reload the view layout.
open func reload() {
isOpened = false
layoutViews()
guard let base = views.first else {
return
}
base.frame.size = baseSize
base.zPosition = 10000
for i in 1..<views.count {
let v = views[i]
v.alpha = 0
v.isHidden = true
v.frame.size = itemSize
v.x = base.x + (baseSize.width - itemSize.width) / 2
v.y = base.y + (baseSize.height - itemSize.height) / 2
v.zPosition = CGFloat(10000 - views.count - i)
}
}
/// Disable the Menu if views exist.
fileprivate func disable() {
guard 0 < views.count else {
return
}
isEnabled = false
}
/**
Enable the Menu if the last view is equal to the passed in view.
- Parameter view: UIView that is passed in to compare.
*/
fileprivate func enable(view: UIView) {
guard view == views.last else {
return
}
isEnabled = true
}
}
extension Menu {
/**
Open the Menu component with animation options.
- Parameter duration: The time for each view's animation.
- Parameter delay: A delay time for each view's animation.
......@@ -204,7 +232,9 @@ open class Menu: View {
}
}
}
}
extension Menu {
/**
Open the Menu component with animation options in the Up direction.
- Parameter duration: The time for each view's animation.
......@@ -215,7 +245,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func openUpAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func openUpAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -264,7 +294,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func closeUpAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func closeUpAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -307,7 +337,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func openDownAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func openDownAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -358,7 +388,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func closeDownAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func closeDownAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -403,7 +433,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func openLeftAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func openLeftAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -452,7 +482,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func closeLeftAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func closeLeftAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -495,7 +525,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func openRightAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func openRightAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -546,7 +576,7 @@ open class Menu: View {
- Parameter animations: An animation block to execute on each view's animation.
- Parameter completion: A completion block to execute on each view's animation.
*/
private func closeRightAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
fileprivate func closeRightAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) {
guard let base = views.first else {
return
}
......@@ -580,43 +610,4 @@ open class Menu: View {
}
}
}
/// Layout the views.
private func layoutViews() {
guard let base = views.first else {
return
}
base.frame.size = baseSize
base.zPosition = 10000
for i in 1..<views.count {
let v = views[i]
v.alpha = 0
v.isHidden = true
v.frame.size = itemSize
v.x = base.x + (baseSize.width - itemSize.width) / 2
v.y = base.y + (baseSize.height - itemSize.height) / 2
v.zPosition = CGFloat(10000 - views.count - i)
}
}
/// Disable the Menu if views exist.
private func disable() {
guard 0 < views.count else {
return
}
isEnabled = false
}
/**
Enable the Menu if the last view is equal to the passed in view.
- Parameter view: UIView that is passed in to compare.
*/
private func enable(view: UIView) {
guard view == views.last else {
return
}
isEnabled = true
}
}
......@@ -49,6 +49,8 @@ extension UIViewController {
}
open class MenuController: RootController {
open fileprivate(set) var blurView: UIView?
/// Reference to the MenuView.
@IBInspectable
open let menu = Menu()
......@@ -88,12 +90,21 @@ extension MenuController {
open func openMenu(completion: ((UIView) -> Void)? = nil) {
if true == isUserInteractionEnabled {
isUserInteractionEnabled = false
UIView.animate(withDuration: 0.15, animations: { [weak self] in
guard let s = self else {
return
if nil == blurView {
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurView = UIView()
blurView?.layout(blur).edges()
view.layout(blurView!).edges()
view.bringSubview(toFront: menu)
}
s.rootViewController.view.alpha = 0.15
})
// UIView.animate(withDuration: 0.15, animations: { [weak self] in
// guard let s = self else {
// return
// }
// s.rootViewController.view.alpha = 0.15
// })
menu.open { [completion = completion] (view) in
completion?(view)
}
......@@ -107,12 +118,16 @@ extension MenuController {
*/
open func closeMenu(completion: ((UIView) -> Void)? = nil) {
if false == isUserInteractionEnabled {
UIView.animate(withDuration: 0.15, animations: { [weak self] in
guard let s = self else {
return
}
s.rootViewController.view.alpha = 1
})
blurView?.removeFromSuperview()
blurView = nil
// UIView.animate(withDuration: 0.15, animations: { [weak self] in
// guard let s = self else {
// return
// }
// s.rootViewController.view.alpha = 1
// })
menu.close { [weak self] (view) in
guard let s = self else {
return
......
......@@ -124,16 +124,6 @@ open class SearchBar: Bar {
}
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
return
}
textField.frame = contentView.bounds
layoutClearButton()
}
/**
An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance.
......@@ -152,6 +142,17 @@ open class SearchBar: Bar {
super.init(frame: frame)
}
open override func layoutSubviews() {
super.layoutSubviews()
guard willLayout else {
return
}
textField.frame = contentView.bounds
layoutLeftView()
layoutClearButton()
}
/**
Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepare method
......@@ -164,16 +165,32 @@ open class SearchBar: Bar {
prepareTextField()
prepareClearButton()
}
}
extension SearchBar {
/// Layout the clearButton.
open func layoutClearButton() {
let h = textField.frame.height
clearButton.frame = CGRect(x: textField.frame.width - h, y: 0, width: h, height: h)
clearButton.frame = CGRect(x: textField.frame.width - h - 4, y: 4, width: h, height: h - 8)
}
/// Layout the leftView.
open func layoutLeftView() {
guard let v = textField.leftView else {
return
}
let h = textField.frame.height
v.frame = CGRect(x: 4, y: 4, width: h, height: h - 8)
(v as? UIImageView)?.contentMode = .scaleAspectFit
}
}
extension SearchBar {
/// Clears the textField text.
@objc
internal func handleClearButton() {
fileprivate func handleClearButton() {
guard nil == textField.delegate?.textFieldShouldClear || true == textField.delegate?.textFieldShouldClear?(textField) else {
return
}
......@@ -189,12 +206,14 @@ open class SearchBar: Bar {
// Live updates the search results.
@objc
internal func handleEditingChanged(textField: UITextField) {
fileprivate func handleEditingChanged(textField: UITextField) {
delegate?.searchBar?(searchBar: self, didChange: textField, with: textField.text)
}
}
extension SearchBar {
/// Prepares the textField.
private func prepareTextField() {
fileprivate func prepareTextField() {
textField.contentScaleFactor = Screen.scale
textField.font = RobotoFont.regular(with: 17)
textField.backgroundColor = Color.clear
......@@ -207,7 +226,7 @@ open class SearchBar: Bar {
}
/// Prepares the clearButton.
private func prepareClearButton() {
fileprivate func prepareClearButton() {
clearButton = IconButton(image: Icon.cm.close, tintColor: placeholderColor)
clearButton.contentEdgeInsets = .zero
isClearButtonAutoHandleEnabled = true
......
......@@ -59,14 +59,6 @@ open class Snackbar: Bar {
open internal(set) var status = SnackbarStatus.hidden
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
/**
Since the subviews will be outside the bounds of this view,
we need to look at the subviews to see if we have a hit.
*/
guard !isHidden else {
return nil
}
for v in subviews {
let p = v.convert(point, from: self)
if v.bounds.contains(p) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment