From 3a546c8adca7cf2298b33ac6e481bcbd300bc48e Mon Sep 17 00:00:00 2001 From: nixzhu Date: Thu, 23 Jul 2015 15:32:13 +0800 Subject: [PATCH] ArrowDirection --- .../ConversationViewController.swift | 27 +++++-- Yep/Views/BubbleMenu/BubbleMenuView.swift | 78 +++++++++++++++---- 2 files changed, 83 insertions(+), 22 deletions(-) diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index bf7f220e..aaa97bc9 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -2194,24 +2194,39 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi menu.hide() } - let menu = BubbleMenuView(items: [copyItem, deleteItem]) + let textViewFrame = cell.convertRect(cell.textContentTextView.frame, toView: strongSelf.view) + + let arrowDirection: BubbleMenuView.ArrowDirection = CGRectGetMidY(textViewFrame) < 64 + 80 ? .Up : .Down + + let menu = BubbleMenuView(arrowDirection: arrowDirection, items: [copyItem, deleteItem]) menu.setTranslatesAutoresizingMaskIntoConstraints(false) strongSelf.view.addSubview(menu) - let textViewFrame = cell.convertRect(cell.textContentTextView.frame, toView: strongSelf.view) - var centerYConstant = CGRectGetMidY(textViewFrame) - CGRectGetMidY(strongSelf.conversationCollectionView.frame) - centerYConstant -= CGRectGetHeight(textViewFrame) - menu.offsetY + var vConstant = CGRectGetMidY(textViewFrame) - CGRectGetMidY(strongSelf.conversationCollectionView.frame) - let menuCenterY = NSLayoutConstraint(item: menu, attribute: .CenterY, relatedBy: .Equal, toItem: strongSelf.view, attribute: .CenterY, multiplier: 1, constant: centerYConstant) + let menuV: NSLayoutConstraint + + switch arrowDirection { + + case .Up: + vConstant += ceil(CGRectGetHeight(textViewFrame) * 0.5) - menu.offsetV + + menuV = NSLayoutConstraint(item: menu, attribute: .Top, relatedBy: .Equal, toItem: strongSelf.view, attribute: .CenterY, multiplier: 1, constant: vConstant) + + case .Down: + vConstant -= ceil(CGRectGetHeight(textViewFrame) * 0.5) - menu.offsetV + + menuV = NSLayoutConstraint(item: menu, attribute: .Bottom, relatedBy: .Equal, toItem: strongSelf.view, attribute: .CenterY, multiplier: 1, constant: vConstant) + } let centerXConstant = CGRectGetMidX(textViewFrame) - CGRectGetMidX(strongSelf.conversationCollectionView.frame) let menuCenterX = NSLayoutConstraint(item: menu, attribute: .CenterX, relatedBy: .Equal, toItem: strongSelf.view, attribute: .CenterX, multiplier: 1, constant: centerXConstant) - NSLayoutConstraint.activateConstraints([menuCenterY, menuCenterX]) + NSLayoutConstraint.activateConstraints([menuV, menuCenterX]) } } diff --git a/Yep/Views/BubbleMenu/BubbleMenuView.swift b/Yep/Views/BubbleMenu/BubbleMenuView.swift index 0b83ad18..5c36bbeb 100644 --- a/Yep/Views/BubbleMenu/BubbleMenuView.swift +++ b/Yep/Views/BubbleMenu/BubbleMenuView.swift @@ -10,17 +10,24 @@ import UIKit class BubbleMenuView: UIView { - var items: [Item] - - var buttons = [UIButton]() + enum ArrowDirection { + case Up + case Down + } struct Item { let title: String let action: BubbleMenuView -> Void } - init(items: [Item]) { + var arrowDirection: ArrowDirection + var items: [Item] + var buttons = [UIButton]() + + init(arrowDirection: ArrowDirection, items: [Item]) { + + self.arrowDirection = arrowDirection self.items = items super.init(frame: CGRectZero) @@ -49,7 +56,7 @@ class BubbleMenuView: UIView { let arrowHeight: CGFloat = 8 let buttonGap: CGFloat = 12 - let offsetY: CGFloat = 8 + let offsetV: CGFloat = 1 func makeUI() { @@ -96,9 +103,23 @@ class BubbleMenuView: UIView { if let firstButton = buttons.first { let firstButtonTop = NSLayoutConstraint(item: firstButton, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0) - let firstButtonBottom = NSLayoutConstraint(item: firstButton, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: -arrowHeight) - NSLayoutConstraint.activateConstraints([firstButtonTop, firstButtonBottom]) + switch arrowDirection { + + case .Up: + + let firstButtonTop = NSLayoutConstraint(item: firstButton, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: arrowHeight) + let firstButtonBottom = NSLayoutConstraint(item: firstButton, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: 0) + + NSLayoutConstraint.activateConstraints([firstButtonTop, firstButtonBottom]) + + case .Down: + + let firstButtonTop = NSLayoutConstraint(item: firstButton, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0) + let firstButtonBottom = NSLayoutConstraint(item: firstButton, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: -arrowHeight) + + NSLayoutConstraint.activateConstraints([firstButtonTop, firstButtonBottom]) + } } } @@ -109,22 +130,47 @@ class BubbleMenuView: UIView { // bubble var roundedRect = rect - roundedRect.size.height -= arrowHeight + + switch arrowDirection { + + case .Up: + roundedRect.origin.y += arrowHeight + roundedRect.size.height -= arrowHeight + + case .Down: + roundedRect.size.height -= arrowHeight + } + let bubblePath = UIBezierPath(roundedRect: roundedRect, cornerRadius: 5) bubblePath.fill() // arrow - let buttomX = CGRectGetMidX(rect) - let buttomY = CGRectGetMaxY(rect) + switch arrowDirection { - let arrowPath = UIBezierPath() - arrowPath.moveToPoint(CGPointMake(buttomX, buttomY)) - arrowPath.addLineToPoint(CGPointMake(buttomX - (arrowHeight - 1), buttomY - arrowHeight)) - arrowPath.addLineToPoint(CGPointMake(buttomX + (arrowHeight - 1), buttomY - arrowHeight)) - arrowPath.closePath() - arrowPath.fill() + case .Up: + let topX = CGRectGetMidX(rect) + let topY = CGRectGetMinY(rect) + + let arrowPath = UIBezierPath() + arrowPath.moveToPoint(CGPointMake(topX, topY)) + arrowPath.addLineToPoint(CGPointMake(topX - (arrowHeight - 1), topY + arrowHeight)) + arrowPath.addLineToPoint(CGPointMake(topX + (arrowHeight - 1), topY + arrowHeight)) + arrowPath.closePath() + arrowPath.fill() + + case .Down: + let buttomX = CGRectGetMidX(rect) + let buttomY = CGRectGetMaxY(rect) + + let arrowPath = UIBezierPath() + arrowPath.moveToPoint(CGPointMake(buttomX, buttomY)) + arrowPath.addLineToPoint(CGPointMake(buttomX - (arrowHeight - 1), buttomY - arrowHeight)) + arrowPath.addLineToPoint(CGPointMake(buttomX + (arrowHeight - 1), buttomY - arrowHeight)) + arrowPath.closePath() + arrowPath.fill() + } // lines