From b1b7365812a33e31f7fe206be8b15baa64c57527 Mon Sep 17 00:00:00 2001 From: Vitalii Tim Date: Mon, 4 Nov 2019 17:30:36 +0200 Subject: [PATCH 1/2] fixed broken corner in case the corner is very close to an edge but not exactly at that edge yet --- Classes/Popover.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Classes/Popover.swift b/Classes/Popover.swift index 6618bf4..2a6aa60 100644 --- a/Classes/Popover.swift +++ b/Classes/Popover.swift @@ -623,11 +623,11 @@ private extension Popover { } var isCornerLeftArrow: Bool { - return self.arrowShowPoint.x == self.frame.origin.x + return self.arrowShowPoint.x <= self.frame.origin.x + arrowSize.width + cornerRadius } var isCornerRightArrow: Bool { - return self.arrowShowPoint.x == self.frame.origin.x + self.bounds.width + return self.arrowShowPoint.x >= (self.frame.origin.x + self.bounds.width) - arrowSize.width - cornerRadius } func radians(_ degrees: CGFloat) -> CGFloat { From 00b0d23c2ad797589a9904a6de0877817a9afdce Mon Sep 17 00:00:00 2001 From: Vitalii Tim Date: Tue, 12 Nov 2019 17:01:35 +0200 Subject: [PATCH 2/2] more corrections for the case when the corner is close to the edge and behind the edge (only applicable for .up position) + added test buttons into the demo app --- Classes/Popover.swift | 85 +++++-- Example/Popover/Base.lproj/Main.storyboard | 247 ++++++++++++++++++++- Example/Popover/ViewController.swift | 9 + 3 files changed, 311 insertions(+), 30 deletions(-) diff --git a/Classes/Popover.swift b/Classes/Popover.swift index 2a6aa60..e9dfc23 100644 --- a/Classes/Popover.swift +++ b/Classes/Popover.swift @@ -298,24 +298,39 @@ open class Popover: UIView { case .down, .auto: arrow.move(to: CGPoint(x: arrowPoint.x, y: 0)) - arrow.addLine( - to: CGPoint( - x: arrowPoint.x + self.arrowSize.width * 0.5, - y: self.isCornerRightArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height + + if self.isCloseToCornerRightArrow && !self.isCornerRightArrow { + if !isBehindCornerRightArrow { + arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height)) + arrow.addArc( + withCenter: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height + self.cornerRadius), + radius: self.cornerRadius, + startAngle: self.radians(270.0), + endAngle: self.radians(0), + clockwise: true) + } else { + arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.arrowSize.height + self.cornerRadius)) + arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.arrowSize.height)) + } + } else { + arrow.addLine( + to: CGPoint( + x: self.isBehindCornerLeftArrow ? self.frame.minX - self.arrowSize.width * 0.5 : arrowPoint.x + self.arrowSize.width * 0.5, + y: self.isCornerRightArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height + ) ) - ) - - arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height)) - arrow.addArc( - withCenter: CGPoint( - x: self.bounds.width - self.cornerRadius, - y: self.arrowSize.height + self.cornerRadius - ), - radius: self.cornerRadius, - startAngle: self.radians(270.0), - endAngle: self.radians(0), - clockwise: true) - + arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height)) + arrow.addArc( + withCenter: CGPoint( + x: self.bounds.width - self.cornerRadius, + y: self.arrowSize.height + self.cornerRadius + ), + radius: self.cornerRadius, + startAngle: self.radians(270.0), + endAngle: self.radians(0), + clockwise: true) + } + arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - self.cornerRadius)) arrow.addArc( withCenter: CGPoint( @@ -339,6 +354,8 @@ open class Popover: UIView { clockwise: true) arrow.addLine(to: CGPoint(x: 0, y: self.arrowSize.height + self.cornerRadius)) + + if !isBehindCornerLeftArrow { arrow.addArc( withCenter: CGPoint( x: self.cornerRadius, @@ -348,10 +365,18 @@ open class Popover: UIView { startAngle: self.radians(180), endAngle: self.radians(270), clockwise: true) + } - arrow.addLine(to: CGPoint( - x: arrowPoint.x - self.arrowSize.width * 0.5, - y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height)) + if isBehindCornerRightArrow { + arrow.addLine(to: CGPoint( + x: self.bounds.width - self.arrowSize.width * 0.5, + y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height)) + } else if isCloseToCornerLeftArrow && !isCornerLeftArrow { + () // skipping this line in that case + } else { + 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)) @@ -622,12 +647,28 @@ private extension Popover { }, completion: nil) } + var isCloseToCornerLeftArrow: Bool { + return self.arrowShowPoint.x < self.frame.origin.x + arrowSize.width/2 + cornerRadius + } + + var isCloseToCornerRightArrow: Bool { + return self.arrowShowPoint.x > (self.frame.origin.x + self.bounds.width) - arrowSize.width/2 - cornerRadius + } + var isCornerLeftArrow: Bool { - return self.arrowShowPoint.x <= self.frame.origin.x + arrowSize.width + cornerRadius + return self.arrowShowPoint.x == self.frame.origin.x } var isCornerRightArrow: Bool { - return self.arrowShowPoint.x >= (self.frame.origin.x + self.bounds.width) - arrowSize.width - cornerRadius + return self.arrowShowPoint.x == self.frame.origin.x + self.bounds.width + } + + var isBehindCornerLeftArrow: Bool { + return self.arrowShowPoint.x < self.frame.origin.x + } + + var isBehindCornerRightArrow: Bool { + return self.arrowShowPoint.x > self.frame.origin.x + self.bounds.width } func radians(_ degrees: CGFloat) -> CGFloat { diff --git a/Example/Popover/Base.lproj/Main.storyboard b/Example/Popover/Base.lproj/Main.storyboard index 48f2720..aaee96f 100644 --- a/Example/Popover/Base.lproj/Main.storyboard +++ b/Example/Popover/Base.lproj/Main.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -42,7 +40,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -105,7 +336,7 @@ - + @@ -113,7 +344,7 @@ - + diff --git a/Example/Popover/ViewController.swift b/Example/Popover/ViewController.swift index a5ec28c..7f689ca 100644 --- a/Example/Popover/ViewController.swift +++ b/Example/Popover/ViewController.swift @@ -80,6 +80,15 @@ class ViewController: UIViewController { let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) popover.show(aView, fromView: self.rightCenterButton) } + + @IBAction func tappedAPositionButton(_ 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(.auto), .showBlackOverlay(false)] + let popover = Popover(options: options, showHandler: nil, dismissHandler: nil) + popover.show(aView, fromView: sender) + } + } extension ViewController: UITableViewDelegate {