I used BlocksKit a lot during the OC era, and before RAC was introduced, BlocksKit made code a lot more elegant. However, with the release of Swift, the Run-time approach is no longer recommended because Swift is a strongly typed language. In Swift, if you want to use runtime features you need special declarations like @objc. Therefore, Blockskit does not have a SWIFT version. However, even if you remove some of the Runtime stuff, Blockskit has some useful extensions. So, I wrote my own list of common approaches to Blockskit that I could think of and do: ClosuresKit. There are mainly the following three parts of the expansion

Foundation

Collection type increment API

  • Cs_match finds a match based on the closure passed in. A filter returns a collection. Match returns only one. The following is an example:

    Let testSequence = [2,5,6,9] func testMatch() {let result = testSequence. Cs_match {(value) -> Bool in return value == 5 } assert(result==5,"match failed") }Copy the code
  • The cs_any argument, as before, returns a Boolean value that determines whether any data in the collection matches the closure passed in.
  • The cs_all argument, as before, returns a Boolean value that determines whether all data in the collection matches the closure passed in.
  • The cs_none argument, as before, returns a Boolean value that is passed to determine if there is no data in the collection that matches the closure.

NSObject makes it easy to associate objects

Methods that encapsulate objc_setAssociatedObject of NSObject. The difference between these apis is that the associated policies are different, such as Reatian, copy, weak, etc.

class AssocaitedObjectTests: XCTestCase {
    static var identifier = "identifier"

    func testCopyAssociateValue(){
        let test:NSMutableString="first"
        let view = UIView()
        view.cs_associateCopyOfValue(test, key: &AssocaitedObjectTests.identifier)
        test.appendString("t")
        let result = view.cs_associateValueForKey(&AssocaitedObjectTests.identifier) as! NSString
        assert(result=="first","CopyAssociateValue failed")
    }

}Copy the code

This is an example code for copy associated object policies written in unit tests.

notice

Can add to a notice through cs_addNotificationObserverForName convenient processing:

func testObserverNotification() { let notificationName = "Test" cs_addNotificationObserverForName(name: "Test", object: nil) { (notification) in assert(notification.userInfo! ["value"] as! String == "param",#function) } NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: self,userInfo:["value":"param"]) }Copy the code

NSTimer

Callbacks can be handled directly by passing in a closure when a timer is added. Sample code:

var count=0 var timer:NSTimer? func testTimerWithtimeInterval() { timer = NSTimer.cs_scheduledTimerWithTimeInterval(1, repeats: false, userInfo: ["key":"value"]) {[unowned self] (timer) in assert(timer.userInfo! ["key"]=="value", #function) print("times:\(self.count)") } timer! .fire() }Copy the code

UIKIt

Cs_addEventHandlerForEvents adds a method to UIControlEvents to make it easier to handle UIControlEvents as shown in the following example:

   btn.cs_addEventHandlerForEvents(.TouchUpInside) { (sender) in
            print("TouchUpInside")
        }Copy the code

UIGesture

You can easily add gestures directly to UIView, support chained programming, can be configured in the closure when adding gestures, handle several different states in succession:

     label.cs_addPanGesture { (gestureRecognizer) in
            gestureRecognizer.maximumNumberOfTouches=2
        }.whenBegan { (gestureRecognizer) in
            print("began")
        }Copy the code

If no configuration is required, the configured closure can be empty:

       label.cs_addPanGesture().whenChanged { (gestureRecognizer) in
            print("changed")
        }Copy the code

It is also possible to add the same processing closure to several states simultaneously:

lbState.nc_addPanGesture().whenStatesHappend([.Ended,.Changed]) { (gestureRecognizer) -> Void in

        }Copy the code

We also added two quick handling methods for tap and swipe:

    label.cs_whenTapped { (tapGestureRecognizer) in
            print("tapped")
        }

     view.cs_whenSwipedInDirection(.Down) { (gestureRecognizer) in
            print("down")
        }Copy the code

At present, these are the APIS I have in mind. If there is anything that needs to be added, you can directly mention it in the issue, AND I will deal with it in time. You are also welcome to directly mention pull Request.

Welcome to start support comments: github.com/lacklock/Cl…

Author: Zhuo without a story

Author’s Microblog:No story, Zhuo

This article is from:Jane’s book