Как переупорядочить uitableviewcell, не показывая управление переупорядочением? - PullRequest
5 голосов
/ 07 октября 2011

Я использую spliviewcontroller для приложения ipad.Я также реализовал переупорядочение для uitableview, которое слева от spliview.Я хочу добиться того, чтобы пользователь мог изменить порядок таблицы, но не нужно трогать три белые полосы.Пользователь должен иметь возможность прикоснуться к любой ячейке и изменить ее порядок.Возможно ли это?

Ответы [ 5 ]

3 голосов
/ 11 октября 2014

Класс ниже скрывает элемент управления переупорядочением и делает весь UITableViewCell доступным для переупорядочения. Кроме того, он позаботится о том, чтобы изменить размер представления контента до его исходного размера, что важно для автоматической разметки.

@interface UITableViewCellReorder : UITableViewCell
{
    __weak UIView *_reorderControl;
}

@implementation UITableViewCellReorder

#define REORDER_CONTROL_CLASSNAME @"UITableViewCellReorderControl"

/*
 Override layoutSubviews to resize the content view's frame to its original size which is the size 
 of the cell. This is important for autolayout!
 Do not call this method on super, as we don't need any further layouting wihtin the cell itself.
 */

- (void)layoutSubviews
{
    self.contentView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    [self setAndHideReorderControl];
}

/*
 Find the reorder control, store a reference and hide it.
 */

- (void) setAndHideReorderControl
{
    if (_reorderControl)
        return;

    // > iOS 7
    for(UIView* view in [[self.subviews objectAtIndex:0] subviews])
        if([[[view class] description] isEqualToString:REORDER_CONTROL_CLASSNAME])
            _reorderControl = view;

    // < iOS 7
    if (!_reorderControl)
        for(UIView* view in self.subviews)
            if([[[view class] description] isEqualToString:REORDER_CONTROL_CLASSNAME])
                _reorderControl = view;

    if (_reorderControl)
    {
        [_reorderControl setHidden:YES];
    }
}


#pragma mark - Touch magic

/*
 Just perform the specific selectors on the hidden reorder control to fire touch events on the control.
 */

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_reorderControl && [_reorderControl respondsToSelector:@selector(beginTrackingWithTouch:withEvent:)])
    {
        UITouch * touch = [touches anyObject];
        [_reorderControl performSelector:@selector(beginTrackingWithTouch:withEvent:) withObject:touch withObject:event];
    }

    [super touchesBegan:touches withEvent:event];
    [self.nextResponder touchesBegan:touches withEvent:event];
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_reorderControl && [_reorderControl respondsToSelector:@selector(continueTrackingWithTouch:withEvent:)])
    {
        UITouch * touch = [touches anyObject];
        [_reorderControl performSelector:@selector(continueTrackingWithTouch:withEvent:) withObject:touch withObject:event];
    }

    [super touchesMoved:touches withEvent:event];
    [self.nextResponder touchesMoved:touches withEvent:event];
}

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_reorderControl && [_reorderControl respondsToSelector:@selector(cancelTrackingWithEvent:)])
    {
        [_reorderControl performSelector:@selector(cancelTrackingWithEvent:) withObject:event];
    }

    [super touchesCancelled:touches withEvent:event];
    [self.nextResponder touchesCancelled:touches withEvent:event];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_reorderControl && [_reorderControl respondsToSelector:@selector(endTrackingWithTouch:withEvent:)])
    {
        UITouch * touch = [touches anyObject];
        [_reorderControl performSelector:@selector(endTrackingWithTouch:withEvent:) withObject:touch withObject:event];
    }

    [super touchesEnded:touches withEvent:event];
    [self.nextResponder touchesEnded:touches withEvent:event];
}

@end
2 голосов
/ 12 марта 2012
1 голос
/ 05 июня 2016

Я взял ответ от ANami и объединил его с другим постом, чтобы он работал с Xcode 7.3 и iOS 9 с использованием Swift 2.2

Я бы предложил использовать это как базовый класс:

    //
    //  MoveableTableViewCell.swift
    //  ReorderTableTest
    //
    //  Created by Geoff on 05/06/16.
    //  Copyright © 2016 Think#. MIT License, free to use.
    //

    import UIKit

    class MoveableTableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    override func setEditing(editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: true)
        //self.showsReorderControl = false

        if (editing) {


            for view in subviews as [UIView] {
                if view.dynamicType.description().rangeOfString("Reorder") != nil {

                    // resized grip
                    let resized = UIView(frame: CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame)))
                    resized.addSubview(view)
                    self.addSubview(resized)

                    // remove image
                    for img:AnyObject in view.subviews {
                        if (img is UIImageView) {
                            (img as! UIImageView).image = nil
                        }
                    }

                    // determine diff and ratio
                    let diff = CGSizeMake(resized.frame.width - view.frame.width, resized.frame.height - view.frame.height)
                    let ratio = CGSizeMake(resized.frame.width / view.frame.width, resized.frame.height / view.frame.height)

                    // transform!
                    var transform = CGAffineTransformIdentity
                    transform = CGAffineTransformScale(transform, ratio.width, ratio.height)
                    transform = CGAffineTransformTranslate(transform, -diff.width / 2.0, -diff.height / 2.0)
                    resized.transform = transform


                }
            }
        }
    }

}
1 голос
/ 21 июля 2014

Я знаю, что это старый вопрос, но вот помощник Swift , который должен помочь будущим искателям приключений.

/*
    THIS IS A HACK!
    It uses undocumented controls and class names, and will need to be revised with every iOS release.

    Usage:
        Call the 'transform' method after the cell is displayed - i.e. tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell! ...

    Adopted from:
        http://b2cloud.com.au/how-to-guides/reordering-a-uitableviewcell-from-any-touch-point

    In case of failure: 
        - print names of all subviews
        - find the new 'UITableViewCellReorderControl' and reflect changes to the code below
*/
struct MovableTableViewCell {
    static func transform(cell:UITableViewCell) {
        var reorder = cell.getSubviewByName("UITableViewCellReorderControl")

        if (reorder == nil) {
            println("UITableViewCellReorderControl was not found. Reorder control will remain unchanged.")
            return
        }

        // resized grip
        var resized = UIView(frame: CGRectMake(0, 0, CGRectGetMaxX(reorder!.frame), CGRectGetMaxY(reorder!.frame)))
        resized.addSubview(reorder!)
        cell.addSubview(resized)

        // remove image
        for img:AnyObject in reorder!.subviews {
            if (img is UIImageView) {
                (img as UIImageView).image = nil
            }
        }

        // determine diff and ratio
        var diff = CGSizeMake(resized.frame.width - reorder!.frame.width, resized.frame.height - reorder!.frame.height)
        var ratio = CGSizeMake(resized.frame.width / reorder!.frame.width, resized.frame.height / reorder!.frame.height)

        // transform!
        var transform = CGAffineTransformIdentity
        transform = CGAffineTransformScale(transform, ratio.width, ratio.height)
        transform = CGAffineTransformTranslate(transform, -diff.width / 2.0, -diff.height / 2.0)
        resized.transform = transform
    }
}


extension UIView {
    func getSubviewByName(name:String) -> UIView? {

        if (object_getClassName(self) == name.bridgeToObjectiveC().UTF8String) {
            return self
        }

        for v in (self.subviews as Array<UIView>) {
            var child = v.getSubviewByName(name)

            if (child != nil) {
                return child
            }
        }

        return nil
    }
}
0 голосов
/ 22 сентября 2015

Вот код, который я написал, который позволит вам изменить порядок ячеек, основываясь на том, что пользователь касается любой части ячейки. Я вложил в подкласс UITableView и использовал методы touchesBegan и touchesEnded, чтобы выяснить, какая ячейка была повернута, и переместить ее вперед и назад. Это довольно простой код, дайте мне знать, если у вас есть какие-либо вопросы.

class ReorderTableView: UITableView {

var customView:UIImageView?
var oldIndexPath:NSIndexPath?

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    guard let touch1 = touches.first else{
        return
    }

    oldIndexPath = self.indexPathForRowAtPoint(touch1.locationInView(self))
    guard (oldIndexPath != nil) else{
        return
    }
    let oldCell = self.cellForRowAtIndexPath(self.oldIndexPath!)

    customView = UIImageView(frame: CGRectMake(0, touch1.locationInView(self).y - 20, self.frame.width, 40))
    customView?.image = screenShotView(oldCell!)
    customView?.layer.shadowColor = UIColor.blackColor().CGColor
    customView?.layer.shadowOpacity = 0.5
    customView?.layer.shadowOffset = CGSizeMake(1, 1)

    self.addSubview(customView!)
    oldCell?.alpha = 0
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    guard let touch1 = touches.first else{
        return
    }
    let newIndexPath = self.indexPathForRowAtPoint(touch1.locationInView(self))
    guard newIndexPath != nil else{
        return
    }
    guard oldIndexPath != nil else{
        return
    }
    if newIndexPath != oldIndexPath{
        self.moveRowAtIndexPath(oldIndexPath!, toIndexPath: newIndexPath!)
        oldIndexPath = newIndexPath
        self.cellForRowAtIndexPath(self.oldIndexPath!)!.alpha = 0
    }
    self.customView!.frame.origin = CGPointMake(0, touch1.locationInView(self).y - 20)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    self.customView?.removeFromSuperview()
    self.customView = nil
    guard (oldIndexPath != nil) else{
        return
    }
    self.cellForRowAtIndexPath(self.oldIndexPath!)!.alpha = 1
}

func screenShotView(view: UIView) -> UIImage? {

    let rect = view.bounds
    UIGraphicsBeginImageContextWithOptions(rect.size,true,0.0)
    let context = UIGraphicsGetCurrentContext()

    CGContextTranslateCTM(context, 0, -view.frame.origin.y);
    self.layer.renderInContext(context!)
    let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return capturedImage
}

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...