Without further ado, the effect is as follows:

—Github—

Use # #

class HKTabBarViewController: UITabBarController {

override func viewDidLoad() { super.viewDidLoad() ... viewControllers = [vc0, vc1, Vc2] /** * imageName imageName * title text * distance maximum offset * mini_x_Coef small image x offset * mini_y_Coef small image y offset */let item = HKTabBarModel(imageName: "recent", title: "News", distance: 10, mini_x_Coef: 0.2, mini_y_Coef: 0.4)
    let item1 = HKTabBarModel(imageName: "buddy", title: "Contact")
    let item2 = HKTabBarModel(imageName: "qworld", title: "Dynamic", distance: 10, mini_x_Coef: -0.2, mini_y_Coef: 0.2)

    // let tabbar = HKTabBar(items: [item, item1, item2])
    // tabbar.hk_delegate = self

    let tabbar = HKTabBar(items: [item, item1, item2]) { (btn, index) in
        print(btn? .title ??"title")
        self.selectedIndex = index
    }

        self.setValue(tabbar, forKey: "tabBar")
    }
}

//extension HKTabBarViewController: HKTabBarDelegate {
//    func hk_tabBar(_ tabBar: HKTabBar, didSelect item: HKDragButton, index: Int) {
//         self.selectedIndex = index
//    }
//}
Copy the code

# # analysis

By analyzing the animation effect, we can guess that QQ TabBar places two pictures on the button. When dragging and dropping, the two pictures have different offsets respectively (found in QQ’s resource pack, such pictures are indeed made of two pictures).

#### work So, there are several key points to achieve this effect (the key points are not the difficult ones are easy),

######1. Make the button respond to the drag (PAN) gesture, and calculate the offset code of the two pictures according to the position of the finger as follows

//distance maximum offset // dragButton_x & dragButton_y // var point = pan.location()in: self)
         point = CGPoint(x: point.x - bounds.size.width * 0.5, y:  point.y - bounds.size.height * 0.5)
         let X = point.x
         let Y = point.y
         let R = sqrt(pow(X , 2) + pow(Y , 2))
         let scale = R / distance
         self.dragButton_x = X / scale
         self.dragButton_y = Y / scale
Copy the code

######2. Change the image location

//mini_x_Coef,mini_y_Coef is a small map offset difference in order to create"Three dimensions."Effect private funcdragIcon() {
        letX = (bounds.size. Width - imageview_big.bounds.size. Width) * 0.5 + dragButton_xletHeight) * 0.5 + dragButton_y self.imageView_big.frame = CGRect(x: x, y: y, width: self.imageView_big.bounds.size.width, height: self.imageView_big.bounds.size.height ) self.imageView_mini.frame = CGRect(x: x + self.dragButton_x * mini_x_Coef, y: y + self.dragButton_y * mini_y_Coef, width: self.imageView_big.bounds.size.width, height: self.imageView_big.bounds.size.height ) }Copy the code

######3. Let go

Self.dragbutton_y = 0 self.dragButton_x = 0 UIView.animate(withDuration: Self.imageview_big.frame = CGRect(x: 0.0, y: 0.0, width: self.itemw, height: 0) {self.imageview_big.frame = CGRect(x: 0.0, y: 0.0, width: self.itemw, height: 0) Self.itemh-15.0) self.imageView_mini-frame = CGRect(x: 0.0, y: 0.0, width: self.itemw, height: self.itemh-15.0)}Copy the code

######4. Select the animation

// Change the image first... Uiview.animate (withDuration: 0.2, animations: {self.imageview_big.transform = CGAffineTransform(scaleX:) uiView.animate (withDuration: 0.2, animations: {self.imageview_big.transform = CGAffineTransform(scaleX:) Self.imageview_mini. Transform = CGAffineTransform(scaleX: 0.85, y: 0.85) {(_) self.imageView_mini. Transform = CGAffineTransform(scaleX: 0.85, y: 0.85)}) {(_)inUiview.animate (withDuration: 0.2, animations: {self.imageview_big. transform = CGAffineTransform(scaleX: 1, y: animations: {self.imageview_big. transform = CGAffineTransform(scaleX: 1, y: 1) self.imageView_mini.transform = CGAffineTransform(scaleX: 1, y: 1) }) }Copy the code

Above is the main code Github < implement QQ TabBar drag and drop effect >