2011-10-07 24 views
2

私はipadアプリケーションのためにspliviewcontrollerを使用しています。また、spliviewの左側にあるuitableviewの並べ替えを実装しました。私が達成したいのは、ユーザーがtableCellを並べ替えることができますが、3つの白い棒に触れる必要はありません。ユーザーはセルのどこに触れてもそれを並べ替えることができるはずです。出来ますか?並べ替えコントロールを表示せずにuitableviewcellを並べ替えるにはどうすればいいですか?

+0

[Reordering reorder controlなしでReordering UITableView](http://stackoverflow.com/questions/5624730/reordering-uitableview-without-reorder-control) –

+0

私はこの回答に遭遇しました。それは助けになるかもしれません..簡単な解決策ではありませんが、うまくいくはずです:http://stackoverflow.com/questions/5624730/reordering-uitableview-without-reorder-control –

答えて

1

私はそれが古い質問だと知っていますが、スウィフト助手が将来の冒険を求めるのに役立つはずです。

/* 
    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

+1非常にニース、なぜあなたはあなたの答えにライブラリとホストと言及を作っていないのですか? – mAc

3

以下のクラスは、リオーダコントロールを非表示にして並べ替えのための全体の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 
0

は、私はそれはあなたがセルの任意の部分に触れるユーザーに基づいてセルを並べ替えるようになる書いたいくつかのコードです。私はUITableViewをサブクラス化し、どのセルがタップされたかを把握し、前後に移動させるためにtouchesBeganとのメソッドを使用しました。その基本的なコードは、ご質問がある場合はお知らせください。

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 
} 

} 
1

私は、基本クラスとしてこれを使用することをお勧めANamiからの回答を取り、それはスウィフト2.2

を使用してのXcode 7.3とiOS 9で動作させるために別のポストでそれをマージ:

// 
    // 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 


       } 
      } 
     } 
    } 

} 
関連する問題