20

私はニュース リーダー アプリを実行しています。ユーザーがニュース カテゴリ (トップ ニュース、ビジネス、テクノロジー、スポーツなど) の表示/非表示を選択し、Android の BBC ニュース アプリのように並べ替えられるようにしたいと考えています。

下の図を参照してください。

ここに画像の説明を入力

私の質問は:

  • セルの左側で並べ替えコントロールを作成するにはどうすればよいですか? (デフォルトの位置は、編集モードのセルの右側です)
  • チェックボックスのカスタム コントロールがあります。セルの右側に配置するにはどうすればよいですか?
4

10 に答える 10

38

回答 [アクセサリを使用していない場合 (詳細開示など)]

(0) テーブルがセットアップされていると思います &c.

(1) このソリューションは、テーブル セルが常にドラッグ可能な場合にのみ機能します。これを viewDidLoad で Table View Controller .m ファイルに追加します。

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setEditing:YES];
}

(2) セルを並べ替えられるようにするcell.showsReorderControl = YES;には、tableView:cellForRowAtIndexPath: に追加します。

(3) tableView:canMoveRowAtIndexPath: および tableView:moveRowAtIndexPath:toIndexPath: メソッドがあることを確認します。

- (BOOL)tableView:(UITableView *)tableview canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES; 
}

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}

(4) 左側に並べ替えコントロールが必要なため、通常そこにある削除円を削除する必要があり、tableView:editingStyleForRowAtIndexPath: メソッドがそれを行います。

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleNone;
}

(5) 魔法が起こる最後のステップ - tableView:willDisplayCell:forRowAtIndexPath: メソッドを追加し、セルのサブビューを検索し、プライベート UITableViewCellReorderControl に絞り込み、最後にそれをオーバーライドします。

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    for(UIView* view in cell.subviews)
    {
        if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])
        {
            // Creates a new subview the size of the entire cell
            UIView *movedReorderControl = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];
            // Adds the reorder control view to our new subview
            [movedReorderControl addSubview:view];
            // Adds our new subview to the cell
            [cell addSubview:movedReorderControl];
            // CGStuff to move it to the left
            CGSize moveLeft = CGSizeMake(movedReorderControl.frame.size.width - view.frame.size.width, movedReorderControl.frame.size.height - view.frame.size.height);
            CGAffineTransform transform = CGAffineTransformIdentity;
            transform = CGAffineTransformTranslate(transform, -moveLeft.width, -moveLeft.height);
            // Performs the transform
            [movedReorderControl setTransform:transform];
        }
    }
}

アクセサリの場合の解決策を見つけようとして 10 時間近く費やしましたが、それができませんでした。まずは経験と知識が必要です。開示ボタンの並べ替えコントロールに同じことを行うだけでは機能しませんでした。したがって、これが今のところうまくいくことを願っています。将来それを理解したら、必ずこれを更新します。

Hoang Van Ha さん、これが初めての回答です。Objective-C の学習を始めてまだ 1 か月しか経っていないので、まだ初心者です。

私は自分のアプリで同じことをしようとしていて、その方法を何時間も探していました。これに関しては、Apple のドキュメントはあまり役に立ちません。人々が単にドキュメントにリンクするだけだと、私は非常に苛立たしいと感じました。私は彼らに怒鳴りたかった。私の答えがお役に立てば幸いです。

この記事のコードの一部を使用し、回答に合わせて調整したため、b2Cloud に多くの賞賛を送りました。

于 2012-06-22T22:14:40.387 に答える
24

非公開 API であり、将来変更される可能性がある を探す代わりにUITableViewCellReorderControl、を使用して独自の並べ替えロジックを実装することをお勧めします。UILongPressGestureRecognizerUITableView

HPReorderTableViewUITableView のドロップイン置換である一般的なケース (セルの任意の部分を長押しすることに応答する) を解決しました。たとえばgestureRecognizer:shouldReceiveTouch:reorderGestureRecognizerデリゲートを実装することにより、セルの特定の部分へのタッチに応答するように簡単に変更できます。

于 2014-01-22T10:46:22.063 に答える
4

Luke Dubert は、iOS 7 のクールな答えを持っています。少し変更する必要があります。

UIView *cellSubview = cell.subviews[0];
    for(UIView* view in cellSubview.subviews)
    {
        if([[[view class] description] isEqualToString:@"UITableViewCellReorderControl"])
        {
于 2013-12-17T07:56:06.333 に答える
1

このソリューションは iOS7 では機能しなかったため、両方のバージョンを作成しました。これが役立つことを願っています。

- (void)moveReorderControl:(UITableViewCell *)cell subviewCell:(UIView *)subviewCell
{
    if([[[subviewCell class] description] isEqualToString:@"UITableViewCellReorderControl"]) {
    static int TRANSLATION_REORDER_CONTROL_Y = -20;

        //Code to move the reorder control, you change change it for your code, this works for me
        UIView* resizedGripView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,    CGRectGetMaxX(subviewCell.frame), CGRectGetMaxY(subviewCell.frame))];
        [resizedGripView addSubview:subviewCell];
        [cell addSubview:resizedGripView];

        //  Original transform
        const CGAffineTransform transform = CGAffineTransformMakeTranslation(subviewCell.frame.size.width - cell.frame.size.width, TRANSLATION_REORDER_CONTROL_Y);
        //  Move custom view so the grip's top left aligns with the cell's top left

        [resizedGripView setTransform:transform];
   }
}

//This method is due to the move cells icons is on right by default, we need to move it.
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (tableView.tag == MEETING_BLOCK_TABLE_TAG) {
        for(UIView* subviewCell in cell.subviews)
        {
            if ([ROCFunctions isIOS7]) {
                if([[[subviewCell class] description] isEqualToString:@"UITableViewCellScrollView"]) {
                    for(UIView* subSubviewCell in subviewCell.subviews) {
                        [self moveReorderControl:cell subviewCell:subSubviewCell];
                    }
                }
            }
            else{
                [self moveReorderControl:cell subviewCell:subviewCell];
            }
        }
    }
}
于 2013-10-21T09:49:24.167 に答える
-1

私は、何かを絶対に手動で配置する必要がなく、編集モードとの間のアニメーション化されたトランジションでも機能する、はるかに簡単なソリューションを見つけました。iOS6 と 7 の両方で動作するはずです。

UIView でこのカテゴリをどこかに定義します。

@interface UIView (ClassSearch)

- (instancetype)subviewOfClassMatching:(NSString*)partialName;

@end

@implementation UIView (ClassSearch)

-(instancetype)subviewOfClassMatching:(NSString *)partialName
{
    if ([[[self class] description] rangeOfString:partialName options:NSCaseInsensitiveSearch].location != NSNotFound) {
        return self;
    }

    for (UIView* v in self.subviews) {
        id match = [v subviewOfClassMatching:partialName];
        if (match) {
            return match;
        }
    }

    return nil;
}

@end

次に、UITableViewCell サブクラスで、willTransitionToState を次のようにオーバーライドします。

-(void)willTransitionToState:(UITableViewCellStateMask)state
{
    [super willTransitionToState:state];

    if (state == UITableViewCellStateShowingEditControlMask) {
        UIView* reorderControl = [self subviewOfClassMatching:@"ReorderControl"];
        UIView* reorderContainer = [[UIView alloc] initWithFrame:self.bounds];
        CGAffineTransform t = CGAffineTransformMakeScale(-1, 1);
        reorderContainer.transform = t;
        [self addSubview:reorderContainer];
        [reorderContainer addSubview:reorderControl];
    }
}

並べ替えコントロールのみを表示するようにセルを構成する必要があることに注意してください。そうしないと、さらに多くの作業を行う必要があります。

于 2014-01-21T13:43:47.367 に答える