Skip to content

Commit

Permalink
Merge pull request #125 from alexbutenko/add_left_right
Browse files Browse the repository at this point in the history
added left/right types
  • Loading branch information
corin8823 authored Apr 17, 2019
2 parents 711458c + 711d9d2 commit 213f9cf
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 8 deletions.
153 changes: 151 additions & 2 deletions Classes/Popover.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ public enum PopoverOption {
case showBlackOverlay(Bool)
case springDamping(CGFloat)
case initialSpringVelocity(CGFloat)
case sideOffset(CGFloat)
}

@objc public enum PopoverType: Int {
case up
case down
case left
case right
case auto
}

Expand All @@ -50,6 +53,7 @@ open class Popover: UIView {
open var highlightCornerRadius: CGFloat = 0
open var springDamping: CGFloat = 0.7
open var initialSpringVelocity: CGFloat = 3
open var sideOffset: CGFloat = 6.0

// custom closure
open var willShowHandler: (() -> ())?
Expand Down Expand Up @@ -120,6 +124,7 @@ open class Popover: UIView {
open func show(_ contentView: UIView, fromView: UIView, inView: UIView) {
let point: CGPoint

//TODO: add left/right auto
if self.popoverType == .auto {
if let point = fromView.superview?.convert(fromView.frame.origin, to: nil),
point.y + fromView.frame.height + self.arrowSize.height + contentView.frame.height > inView.frame.height {
Expand All @@ -142,6 +147,16 @@ open class Popover: UIView {
x: fromView.frame.origin.x + (fromView.frame.size.width / 2),
y: fromView.frame.origin.y + fromView.frame.size.height
), from: fromView.superview)
case .left:
point = inView.convert(
CGPoint(x: fromView.frame.origin.x - sideOffset,
y: fromView.frame.origin.y + 0.5 * fromView.frame.height
), from: fromView.superview)
case .right:
point = inView.convert(
CGPoint(x: fromView.frame.origin.x + fromView.frame.size.width + sideOffset,
y: fromView.frame.origin.y + 0.5 * fromView.frame.height
), from: fromView.superview)
}

if self.highlightFromView {
Expand Down Expand Up @@ -337,6 +352,118 @@ open class Popover: UIView {
arrow.addLine(to: CGPoint(
x: arrowPoint.x - self.arrowSize.width * 0.5,
y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height))

case .left:
arrow.move(to: CGPoint(x: self.bounds.width, y: self.bounds.height * 0.5))
arrow.addLine(
to: CGPoint(
x: self.bounds.width - self.arrowSize.height,
y: self.bounds.height * 0.5 + self.arrowSize.width * 0.5
))

arrow.addLine(to: CGPoint(x:self.bounds.width - self.arrowSize.height, y: self.bounds.height - self.cornerRadius))
arrow.addArc(
withCenter: CGPoint(
x: self.bounds.width - self.arrowSize.height - self.cornerRadius,
y: self.bounds.height - self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(0.0),
endAngle: self.radians(90),
clockwise: true)

arrow.addLine(to: CGPoint(x: self.cornerRadius, y: self.bounds.height))
arrow.addArc(
withCenter: CGPoint(
x: self.cornerRadius,
y: self.bounds.height - self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(90),
endAngle: self.radians(180),
clockwise: true)

arrow.addLine(to: CGPoint(x: 0, y: self.cornerRadius))
arrow.addArc(
withCenter: CGPoint(
x: self.cornerRadius,
y: self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(180),
endAngle: self.radians(270),
clockwise: true)

arrow.addLine(to: CGPoint(x: self.bounds.width - self.arrowSize.height - self.cornerRadius, y: 0))
arrow.addArc(
withCenter: CGPoint(x: self.bounds.width - self.arrowSize.height - self.cornerRadius,
y: self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(270),
endAngle: self.radians(0),
clockwise: true)

arrow.addLine(to: CGPoint(x: self.bounds.width - self.arrowSize.height,
y: self.bounds.height * 0.5 - self.arrowSize.width * 0.5
))
case .right:
arrow.move(to: CGPoint(x: arrowPoint.x, y: self.bounds.height * 0.5))
arrow.addLine(
to: CGPoint(
x: arrowPoint.x + self.arrowSize.height,
y: self.bounds.height * 0.5 + 0.5 * self.arrowSize.width
))

arrow.addLine(
to: CGPoint(
x: arrowPoint.x + self.arrowSize.height,
y: self.bounds.height - self.cornerRadius
))
arrow.addArc(
withCenter: CGPoint(
x: arrowPoint.x + self.arrowSize.height + self.cornerRadius,
y: self.bounds.height - self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(180.0),
endAngle: self.radians(90),
clockwise: false)

arrow.addLine(to: CGPoint(x: self.bounds.width + arrowPoint.x - self.cornerRadius, y: self.bounds.height))
arrow.addArc(
withCenter: CGPoint(
x: self.bounds.width + arrowPoint.x - self.cornerRadius,
y: self.bounds.height - self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(90),
endAngle: self.radians(0),
clockwise: false)

arrow.addLine(to: CGPoint(x: self.bounds.width + arrowPoint.x, y: self.cornerRadius))
arrow.addArc(
withCenter: CGPoint(
x: self.bounds.width + arrowPoint.x - self.cornerRadius,
y: self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(0),
endAngle: self.radians(-90),
clockwise: false)

arrow.addLine(to: CGPoint(x: arrowPoint.x + self.arrowSize.height - self.cornerRadius, y: 0))
arrow.addArc(
withCenter: CGPoint(x: arrowPoint.x + self.arrowSize.height + self.cornerRadius,
y: self.cornerRadius
),
radius: self.cornerRadius,
startAngle: self.radians(-90),
endAngle: self.radians(-180),
clockwise: false)

arrow.addLine(to: CGPoint(x: arrowPoint.x + self.arrowSize.height,
y: self.bounds.height * 0.5 - self.arrowSize.width * 0.5))
}

color.setFill()
Expand Down Expand Up @@ -376,14 +503,22 @@ private extension Popover {
self.springDamping = value
case let .initialSpringVelocity(value):
self.initialSpringVelocity = value
case let .sideOffset(value):
self.sideOffset = value
}
}
}
}

func create() {
var frame = self.contentView.frame
frame.origin.x = self.arrowShowPoint.x - frame.size.width * 0.5

switch self.popoverType {
case .up, .down, .auto:
frame.origin.x = self.arrowShowPoint.x - frame.size.width * 0.5
case .left, .right:
frame.origin.y = self.arrowShowPoint.y - frame.size.height * 0.5
}

var sideEdge: CGFloat = 0.0
if frame.size.width < self.containerView.frame.size.width {
Expand All @@ -409,6 +544,12 @@ private extension Popover {
case .down, .auto:
frame.origin.y = self.arrowShowPoint.y
anchorPoint = CGPoint(x: arrowPoint.x / frame.size.width, y: 0)
case .left:
frame.origin.x = self.arrowShowPoint.x - frame.size.width - self.arrowSize.height
anchorPoint = CGPoint(x: 1, y: 0.5)
case .right:
frame.origin.x = self.arrowShowPoint.x
anchorPoint = CGPoint(x: 0, y: 0.5)
}

if self.arrowSize == .zero {
Expand All @@ -421,7 +562,13 @@ private extension Popover {
let y = self.layer.position.y + (anchorPoint.y - lastAnchor.y) * self.layer.bounds.size.height
self.layer.position = CGPoint(x: x, y: y)

frame.size.height += self.arrowSize.height
switch self.popoverType {
case .up, .down, .auto:
frame.size.height += self.arrowSize.height
case .left, .right:
frame.size.width += self.arrowSize.height
}

self.frame = frame
}

Expand All @@ -446,6 +593,8 @@ private extension Popover {
self.contentView.frame.origin.y = 0.0
case .down, .auto:
self.contentView.frame.origin.y = self.arrowSize.height
case .left, .right:
self.contentView.frame.origin.x = 0
}
self.addSubview(self.contentView)
self.containerView.addSubview(self)
Expand Down
38 changes: 33 additions & 5 deletions Example/Popover/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="NSj-Tm-c7V">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="NSj-Tm-c7V">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand All @@ -33,7 +32,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AzU-kr-bWJ">
<rect key="frame" x="217" y="587" width="122" height="30"/>
<rect key="frame" x="218" y="587" width="121" height="30"/>
<state key="normal" title="Up Table Popover">
<color key="titleColor" red="0.97647058819999999" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
Expand All @@ -42,13 +41,40 @@
<action selector="tappedRightButtomButton:" destination="KqD-tH-A54" eventType="touchUpInside" id="T2M-CW-Ps2"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hnz-ge-EBO">
<rect key="frame" x="22" y="214" width="97" height="30"/>
<state key="normal" title="Right Popover">
<color key="titleColor" red="0.97647058819999999" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="tappedLeftTopButton:" destination="KqD-tH-A54" eventType="touchUpInside" id="34D-Ko-gFf"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iah-Ii-nKg">
<rect key="frame" x="271" y="318.5" width="88" height="30"/>
<state key="normal" title="Left Popover">
<color key="titleColor" red="0.97647058819999999" green="0.29803921570000003" blue="0.37647058820000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="tappedRightCenterButton:" destination="KqD-tH-A54" eventType="touchUpInside" id="BOY-xq-BlQ"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Hnz-ge-EBO" secondAttribute="trailing" constant="20" symbolic="YES" id="9OL-vV-6HY"/>
<constraint firstItem="Hnz-ge-EBO" firstAttribute="leading" secondItem="mU4-u9-D2Y" secondAttribute="leading" id="9rn-Nt-UiG"/>
<constraint firstAttribute="trailingMargin" secondItem="AzU-kr-bWJ" secondAttribute="trailing" constant="20" id="Cpd-ri-2iF"/>
<constraint firstItem="AzU-kr-bWJ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="T43-KC-HyU" secondAttribute="leading" constant="20" symbolic="YES" id="FRT-uG-yS7"/>
<constraint firstItem="Coa-16-dTR" firstAttribute="top" secondItem="AzU-kr-bWJ" secondAttribute="bottom" constant="50" id="PPX-sG-ca1"/>
<constraint firstItem="mU4-u9-D2Y" firstAttribute="leading" secondItem="T43-KC-HyU" secondAttribute="leadingMargin" constant="6" id="fio-zq-5hu"/>
<constraint firstItem="Coa-16-dTR" firstAttribute="top" secondItem="mU4-u9-D2Y" secondAttribute="bottom" constant="150" id="iFN-w0-8JY"/>
<constraint firstItem="Hnz-ge-EBO" firstAttribute="top" secondItem="GhJ-Zb-cpE" secondAttribute="bottom" constant="150" id="lO4-W1-e5I"/>
<constraint firstItem="iah-Ii-nKg" firstAttribute="centerY" secondItem="T43-KC-HyU" secondAttribute="centerY" id="nqF-N0-G3v"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="mU4-u9-D2Y" secondAttribute="trailing" constant="20" symbolic="YES" id="oOR-Bn-KYh"/>
<constraint firstAttribute="trailing" secondItem="iah-Ii-nKg" secondAttribute="trailing" constant="16" id="rKV-ru-HR7"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="nzb-3q-qzp">
Expand All @@ -71,8 +97,10 @@
</navigationItem>
<connections>
<outlet property="leftBottomButton" destination="mU4-u9-D2Y" id="PGo-Q5-eJB"/>
<outlet property="leftTopButton" destination="Hnz-ge-EBO" id="XjL-N8-I97"/>
<outlet property="rightBarButton" destination="Ldu-zQ-aLm" id="qEN-K1-5Pn"/>
<outlet property="rightButtomButton" destination="AzU-kr-bWJ" id="U2x-bB-o4l"/>
<outlet property="rightCenterButton" destination="iah-Ii-nKg" id="VVg-xH-UC7"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="RQK-gj-D3i" sceneMemberID="firstResponder"/>
Expand All @@ -85,7 +113,7 @@
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="NSj-Tm-c7V" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="7tY-02-qw4">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
Expand Down
20 changes: 19 additions & 1 deletion Example/Popover/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class ViewController: UIViewController {
@IBOutlet weak var rightBarButton: UIBarButtonItem!
@IBOutlet weak var leftBottomButton: UIButton!
@IBOutlet weak var rightButtomButton: UIButton!

@IBOutlet weak var leftTopButton: UIButton!
@IBOutlet weak var rightCenterButton: UIButton!

fileprivate var texts = ["Edit", "Delete", "Report"]

fileprivate var popover: Popover!
Expand Down Expand Up @@ -62,6 +64,22 @@ class ViewController: UIViewController {
}
self.popover.show(tableView, fromView: self.rightButtomButton)
}

@IBAction func tappedLeftTopButton(_ sender: UIButton) {
let width = self.view.frame.width / 4
let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width))
let options: [PopoverOption] = [.type(.right), .showBlackOverlay(false)]
let popover = Popover(options: options, showHandler: nil, dismissHandler: nil)
popover.show(aView, fromView: self.leftTopButton)
}

@IBAction func tappedRightCenterButton(_ sender: UIButton) {
let width = self.view.frame.width / 4
let aView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: width))
let options: [PopoverOption] = [.type(.left), .showBlackOverlay(false)]
let popover = Popover(options: options, showHandler: nil, dismissHandler: nil)
popover.show(aView, fromView: self.rightCenterButton)
}
}

extension ViewController: UITableViewDelegate {
Expand Down

0 comments on commit 213f9cf

Please sign in to comment.