Skip to content

Commit

Permalink
Merge pull request #18 from claesjacobsson/remove-squircle
Browse files Browse the repository at this point in the history
Remove squircle
  • Loading branch information
neobeppe committed May 16, 2019
2 parents 6c77cb1 + ca4c6ee commit c3904e0
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 15 deletions.
39 changes: 29 additions & 10 deletions Example/Squircle/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,54 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Ve-mD-hj6">
<rect key="frame" x="97.5" y="23" width="180" height="180"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" secondItem="7Ve-mD-hj6" secondAttribute="height" id="ROU-ku-aGr"/>
<constraint firstAttribute="width" constant="180" id="gsE-6t-CYv"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lGl-LF-bp0">
<rect key="frame" x="97.5" y="264.5" width="180" height="180"/>
<rect key="frame" x="97.5" y="218" width="180" height="180"/>
<color key="backgroundColor" red="0.99328044039999996" green="0.99328044039999996" blue="0.99328044039999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<constraints>
<constraint firstAttribute="width" secondItem="lGl-LF-bp0" secondAttribute="height" id="1Rp-bM-FEw"/>
<constraint firstAttribute="width" constant="180" id="pNA-ht-RrM"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Ve-mD-hj6">
<rect key="frame" x="97.5" y="42.5" width="180" height="180"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="msB-9h-PaP">
<rect key="frame" x="97.5" y="417" width="180" height="180"/>
<color key="backgroundColor" red="0.95029137010097686" green="0.99328044039999996" blue="0.9299465075753629" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<constraints>
<constraint firstAttribute="width" secondItem="7Ve-mD-hj6" secondAttribute="height" id="ROU-ku-aGr"/>
<constraint firstAttribute="width" constant="180" id="gsE-6t-CYv"/>
<constraint firstAttribute="width" constant="180" id="1yx-Ov-zQh"/>
<constraint firstAttribute="width" secondItem="msB-9h-PaP" secondAttribute="height" id="bEb-Zu-MwM"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Sba-Wo-IbC">
<rect key="frame" x="131" y="617" width="113" height="30"/>
<state key="normal" title="Toogle Squircles"/>
<connections>
<action selector="toggleSquircles" destination="vXZ-lx-hvc" eventType="touchUpInside" id="WPo-xV-1FU"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" secondItem="lGl-LF-bp0" secondAttribute="bottom" multiplier="3:2" id="8dN-zP-fzJ"/>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" secondItem="7Ve-mD-hj6" secondAttribute="bottom" multiplier="3:1" id="D1A-VX-JFH"/>
<constraint firstItem="lGl-LF-bp0" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="Em5-m8-jAo"/>
<constraint firstItem="Sba-Wo-IbC" firstAttribute="top" secondItem="7Ve-mD-hj6" secondAttribute="bottom" multiplier="3:1" constant="8" symbolic="YES" id="DBR-Ob-Py6"/>
<constraint firstItem="Sba-Wo-IbC" firstAttribute="top" secondItem="lGl-LF-bp0" secondAttribute="bottom" multiplier="3:2" constant="20" id="Lp7-t1-CcO"/>
<constraint firstItem="7Ve-mD-hj6" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="ZL8-8x-3V6"/>
<constraint firstItem="7Ve-mD-hj6" firstAttribute="width" secondItem="7Ve-mD-hj6" secondAttribute="height" id="mQw-rE-TcF"/>
<constraint firstItem="msB-9h-PaP" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="bsP-Ug-PtU"/>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" secondItem="Sba-Wo-IbC" secondAttribute="bottom" constant="20" id="gmY-nf-Sdx"/>
<constraint firstItem="Sba-Wo-IbC" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="vcQ-58-9e7"/>
<constraint firstItem="Sba-Wo-IbC" firstAttribute="top" secondItem="msB-9h-PaP" secondAttribute="bottom" multiplier="3:3" constant="20" id="x9m-Sa-oGo"/>
<constraint firstItem="lGl-LF-bp0" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="xBN-8B-M7K"/>
</constraints>
</view>
<connections>
<outlet property="squircle1View" destination="7Ve-mD-hj6" id="jWc-uo-ql9"/>
<outlet property="squircle2View" destination="lGl-LF-bp0" id="1WN-QZ-p6v"/>
<outlet property="squircle3View" destination="msB-9h-PaP" id="X4d-Jl-xFK"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
Expand Down
25 changes: 22 additions & 3 deletions Example/Squircle/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,37 @@ class ViewController: UIViewController {

@IBOutlet weak var squircle1View: UIView!
@IBOutlet weak var squircle2View: UIView!
@IBOutlet weak var squircle3View: UIView!

var showSquircles = true {
didSet {
if self.showSquircles {
squircle1View.squircle()
squircle2View.squircleWithBorder(width: 5.0, color: .orange)
squircle3View.squircleWithBorder(width: 5.0, color: .orange)
} else {
squircle1View.removeSquircle()
squircle2View.removeSquircle()
squircle3View.removeSquircleBorder()
}

}
}

override func viewDidLoad() {

super.viewDidLoad()
squircle1View.squircle()
squircle2View.squircleWithBorder(width: 5.0, color: .orange)
showSquircles = true
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}


@IBAction func toggleSquircles() {
showSquircles = !showSquircles
}

}

30 changes: 28 additions & 2 deletions Example/Tests/BasicTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@ class BasicTests: XCTestCase {

func testImplementation() {
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let path = view.layer.squirclePath
XCTAssertNotNil(path)
view.squircle()

// Test that we have a squircle mask
var mask = view.layer.mask
XCTAssertNotNil(mask)

// Test that we can remove the squircle
view.removeSquircle()
mask = view.layer.mask
XCTAssertNil(mask)
}

func testPoints() {
Expand All @@ -21,4 +29,22 @@ class BasicTests: XCTestCase {

XCTAssertNotNil(path)
}

func testBorderImplementation() {
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view.squircleWithBorder(width: 5.0, color: .orange)

// Test that we have a border
var count = borderCount(view: view)
XCTAssertTrue(count == 1)

// Test that we can remove border
view.removeSquircleBorder()
count = borderCount(view: view)
XCTAssertTrue(count == 0)
}

func borderCount(view: UIView) -> Int {
return view.layer.sublayers?.filter({ $0.name == squircleBorderName }).count ?? 0
}
}
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,42 @@ let layer = CALayer()
layer.applySquircleWithBorder(width: CGFloat, color: UIColor)
```

### Remove squircle

To remove the squircle from a UIView:


```swift
view.removeSquircle()
```

or directly on CALayer:


```swift
layer.removeSquircle()
```

If a border has been added to the squircle, both functions above will remove it too.


### Remove border

To remove only the border from a squircle:


```swift
view.removeSquircleBorder()
```

or directly on CALayer:


```swift
layer.removeSquircleBorder()
```


## License

Squircle is available under the MIT license. See the LICENSE file for more info.
37 changes: 37 additions & 0 deletions Squircle/Squircle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,24 @@ extension UIView {
public func squircleWithBorder(width: CGFloat, color: UIColor) {
self.layer.applySquircleWithBorder(width: width, color: color)
}

/**
Remove squircle corner radius and border.
*/
public func removeSquircle() {
self.layer.removeSquircle()
}

/**
Remove squircle border.
*/
public func removeSquircleBorder() {
self.layer.removeSquircleBorder()
}
}

internal let squircleBorderName = "squircleBorder"

extension CALayer {

/**
Expand All @@ -48,11 +64,32 @@ extension CALayer {
public func applySquircleWithBorder(width: CGFloat, color: UIColor) {
applySquircle()
let borderLayer = CAShapeLayer()
borderLayer.name = squircleBorderName
borderLayer.path = squirclePath.cgPath
borderLayer.lineWidth = width
borderLayer.strokeColor = color.cgColor
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.frame = self.bounds
self.addSublayer(borderLayer)
}

/**
Remove the squircle corner radius and border.
*/
public func removeSquircle() {
removeSquircleBorder()
self.mask?.removeFromSuperlayer()
}

/**
Remove the squircle border.
*/
public func removeSquircleBorder() {
self.sublayers?
.filter { layer in return layer.name == squircleBorderName }
.forEach { layer in
layer.removeFromSuperlayer()
}
}

}

0 comments on commit c3904e0

Please sign in to comment.