Painted painted levels: fostered fostered fostered

Tags: “iOS” “QiDragView” by MrLiuQ Review: QiShare team


First, let’s take a look at the effect of QiDragView:

I. QiDragView overall architecture design

Not much to say, shelves composition ~

QiDragView (QiDragSortView for short) is an optional drag-and-drop custom control, which can meet some drag-and-drop sorting business requirements.

How to customize QiDragView?

Before the Demo, here are a few customizable UI configuration properties:

attribute type introduce
rowHeight CGFloat Line height
rowMargin CGFloat Line margin
rowPadding CGFloat Line spacing
columnMargin CGFloat The column margins
columnPadding CGFloat The column spacing
columnCount NSInteger The number of columns
normalColor UIColor Button base font color
selectedColor UIColor Button to select font color

And some logical configuration properties:

attribute type introduce
enabledTitles NSArray<NSString *> canBy clickingTitles (Uplink parameter, default all)
selectedTitles NSArray<NSString *> canThe selectedTitles (Uplink parameter, default all)
titles NSArray<NSString *> Button on thetitles(The uplink parameter is created by titles to create a button)

It’s also easy to use:

  • Setting titles directly creates Buttons for titles.
  • throughdragSortEndedBlock method callback to handle drag and drop business logic: button sorting, button selection, etc

Default configuration usage:

QiDragSortView * dragSortView = [[QiDragSortView alloc] initWithFrame: CGRectMake (. 0, 100.0, and the self. The bounds. The size, width, . 0)]; dragSortView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:.5]; DragSortView. Titles = @ [@ "recommended home page," @ "strange dance weekly," @ "the into translation," @ "QiShare," @ "HULK a gleam of gossip," @ "Qtest way"]. / /! < initial Buttons (required) [self.view addSubview:dragSortView]; / /! Drag method callback: Can get the Button array sorting and selection state dragSortView. DragSortEnded = ^ (NSArray < > UIButton * * _Nonnull buttons) {for (UIButton * Button in buttons) { NSLog(@"title: %@, selected: %i", button.currentTitle, button.isSelected); }};Copy the code

Custom configuration usage:

QiDragSortView * dragSortView = [[QiDragSortView alloc] initWithFrame: CGRectMake (. 0, 100.0, and the self. The bounds. The size, width, . 0)]; dragSortView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:.5]; DragSortView. RowHeight = 50.0; DragSortView. RowMargin = 30.0; DragSortView. RowPadding = 20.0; dragSortView.columnCount = 3; DragSortView. ColumnMargin = 30.0; DragSortView. ColumnPadding = 20.0; dragSortView.normalColor = [UIColor redColor]; dragSortView.selectedColor = [UIColor purpleColor]; DragSortView. EnabledTitles = @ [@ "strange dance weekly," @ "the into translation," @ "QiShare," @ "HULK a gleam of gossip," @ "Qtest way"]. / /! < can click on the Buttons of choice (optional, default selection) dragSortView. SelectedTitles = @ [@ "recommended home page," @ "HULK a gleam of gossip," @ "Qtest way"]. / /! < Buttons > dragsortView. titles = @[@" Buttons ", @"QiShare", @"HULK Line of Chat ", @"Qtest way "]; / /! < initial Buttons (required) [self.view addSubview:dragSortView]; / /! Drag method callback: Can get the Button array sorting and selection state dragSortView. DragSortEnded = ^ (NSArray < > UIButton * * _Nonnull buttons) {for (UIButton * Button in buttons) { NSLog(@"title: %@, selected: %i", button.currentTitle, button.isSelected); }};Copy the code

3. Technical points of QiDragView

3.1 Long press gesture:

Long press gestures corresponding to three kinds of state: UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged, UIGestureRecognizerStateEnded.

state instructions
UIGestureRecognizerStateBegan Long press gesturestart
UIGestureRecognizerStateChanged Long press gestureDrag and drop the(Continuous)
UIGestureRecognizerStateEnded Long press gestureThe end of the
/ /! Long press gestures - (void) longPress: (UILongPressGestureRecognizer *) gesture {UIButton * currentButton = (UIButton *) gesture. The view; if (gesture.state == UIGestureRecognizerStateBegan) { [self bringSubviewToFront:currentButton]; [UIView animateWithDuration:.25 animations:^{ self.originButtonCenter = currentButton.center;  self.originGesturePoint = [gesture locationInView:currentButton]; Currentbutton. transform = CGAffineTransformScale(currentButton.transform, 1.2, 1.2);}]; } else if (gesture.state == UIGestureRecognizerStateEnded) { [UIView animateWithDuration:.25 animations:^{ currentButton.center = self.originButtonCenter; currentButton.transform = CGAffineTransformIdentity;  } completion:^(BOOL finished) { if (self.dragSortEnded) { self.dragSortEnded(self.buttons); } }]; } else if (gesture.state == UIGestureRecognizerStateChanged) { CGPoint gesturePoint = [gesture locationInView:currentButton]; CGFloat deltaX = gesturePoint.x - _originGesturePoint.x; CGFloat deltaY = gesturePoint.y - _originGesturePoint.y; currentButton.center = CGPointMake(currentButton.center.x + deltaX, currentButton.center.y + deltaY); NSInteger fromIndex = currentButton.tag; NSInteger toIndex = [self toIndexWithCurrentButton:currentButton]; if (toIndex >= 0) { currentButton.tag = toIndex; if (toIndex > fromIndex) { for (NSInteger i = fromIndex; i < toIndex; i++) { UIButton *nextButton = _buttons[i + 1]; CGPoint tempPoint = nextButton.center; [UIView animateWithDuration:.5 animations:^{ nextButton.center = self.originButtonCenter; }]; _originButtonCenter = tempPoint; nextButton.tag = i; } } else if (toIndex < fromIndex) { for (NSInteger i = fromIndex; i > toIndex; i--) { UIButton *previousButton = self.buttons[i - 1]; CGPoint tempPoint = previousButton.center; [UIView animateWithDuration:.5 animations:^{ previousButton.center = self.originButtonCenter; }]; _originButtonCenter = tempPoint; previousButton.tag = i; } } [_buttons sortUsingComparator:^NSComparisonResult(UIButton *obj1, UIButton *obj2) { return obj1.tag > obj2.tag; }]; }}}Copy the code

3.2 Configuration Button:

In the setter method for property titles, initialize and configure Buttons.

- (void)setTitles:(NSArray<NSString *> *)titles { _titles = titles; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSInteger differCount = titles.count - self.buttons.count; if (differCount > 0) { for (NSInteger i = self.buttons.count; i < titles.count; i++) { [self.buttons addObject:[self buttonWithTag:i]]; } } else if (differCount < 0) { NSArray *extraButtons = [self.buttons subarrayWithRange:(NSRange){titles.count, self.buttons.count - titles.count}]; [self.buttons removeObjectsInArray:extraButtons]; for (UIButton *button in extraButtons) { [button removeFromSuperview]; } } self.enabledTitles = self.enabledTitles ? : titles; / /! If yes, pass in, otherwise pass in self.selectedTitles = self.selectedTitles? : titles; for (NSInteger i = 0; i < self.buttons.count; i++) { [self.buttons[i] setTitle:titles[i] forState:UIControlStateNormal]; [self.buttons[i] addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]]; / /! < long press gesture [self selectButton: self. [I] forStatus buttons: [self. SelectedTitles containsObject: titles [I]]]. if ([self.enabledTitles containsObject:titles[i]]) { [self.buttons[i] addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; } } for (NSInteger i = 0; i < self.buttons.count; i++) { NSInteger rowIndex = i / self.columnCount; NSInteger columnIndex = i % self.columnCount; CGFloat buttonWidth = (self.bounds.size.width - self.columnMargin * 2 - self.columnPadding * (self.columnCount - 1)) / self.columnCount; CGFloat buttonX = self.columnMargin + columnIndex * (buttonWidth + self.columnPadding); CGFloat buttonY = self.rowMargin + rowIndex * (self.rowHeight + self.rowPadding); self.buttons[i].frame = CGRectMake(buttonX, buttonY, buttonWidth, self.rowHeight); } CGRect frame = self.frame; NSInteger rowCount = ceilf((CGFloat)self.buttons.count / (CGFloat)self.columnCount); frame.size.height = self.rowMargin * 2 + self.rowHeight * rowCount + self.rowPadding * (rowCount - 1); self.frame = frame; }); }Copy the code

Source code address: QiDragView


Recommended articles:

IOS Wireshark Packet capture iOS Charles Packet capture TCP IP address UDP weekly