我在我的ipad应用程序中使用spliviewcontroller。我还对spliview左边的uitableview实施了重新排序。我想要实现的是用户可以重新排序tableCell但不需要触摸三个白条。用户应该能够触摸单元格上的任何位置并重新排序。有可能吗?
答案 0 :(得分: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
答案 1 :(得分:2)
答案 2 :(得分:1)
我知道这是一个古老的问题,但这里有一个 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
}
}
答案 3 :(得分:1)
我从Anami那里得到答案并将其与另一篇文章合并,以便使用Swift 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
}
}
}
}
}
答案 4 :(得分:0)
以下是我编写的一些代码,可让您根据用户触摸单元格的任何部分对单元格进行重新排序。我将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
}
}