다음을 통해 공유


Xamarin.iOS에서 끌어서 놓기

iOS 11에 대한 끌어서 놓기 구현

iOS 11에는 iPad의 애플리케이션 간에 데이터를 복사하는 끌어서 놓기 지원이 포함되어 있습니다. 사용자는 나란히 배치된 앱에서 모든 유형의 콘텐츠를 선택하고 끌거나 앱 아이콘 위로 끌어서 앱을 열고 데이터를 삭제할 수 있도록 할 수 있습니다.

사용자 지정 앱에서 Notes 앱으로 예제 끌어서 놓기

참고 항목

iOS 15 이전에는 i전화 동일한 앱 내에서만 끌어서 놓기를 사용할 수 있습니다. iOS 15에는 앱 간 끌어서 놓기가 도입되었습니다.

콘텐츠를 만들거나 편집할 수 있는 모든 위치에서 끌어서 놓기 작업을 지원하는 것이 좋습니다.

  • 텍스트 컨트롤은 추가 작업 없이 iOS 11에 대해 빌드된 모든 앱에 대해 끌어서 놓기를 지원합니다.
  • 테이블 뷰 및 컬렉션 뷰에는 끌어서 놓기 동작 추가를 간소화하는 iOS 11의 향상된 기능이 포함되어 있습니다.
  • 추가 사용자 지정을 통해 끌어서 놓기를 지원하기 위해 다른 모든 보기를 만들 수 있습니다.

앱에 끌어서 놓기 지원을 추가할 때 다양한 수준의 콘텐츠 충실도를 제공할 수 있습니다. 예를 들어 수신 앱이 끌기 대상에 가장 적합한 항목을 선택할 수 있도록 서식이 지정된 텍스트와 일반 텍스트 버전의 데이터를 모두 제공할 수 있습니다. 끌기 시각화를 사용자 지정하고 한 번에 여러 항목을 끌 수도 있습니다.

텍스트 컨트롤을 사용하여 끌어서 놓기

UITextView 선택한 UITextField 텍스트를 끌어서 텍스트 콘텐츠를 삭제할 수 있습니다.

UITableView를 사용하여 끌어서 놓기

UITableView 에는 테이블 행과의 끌어서 놓기 상호 작용에 대한 기본 제공 처리가 있으므로 기본 동작을 사용하도록 설정하는 몇 가지 방법만 있으면 됩니다.

관련된 두 가지 인터페이스가 있습니다.

  • IUITableViewDragDelegate – 테이블 뷰에서 끌기가 시작될 때 정보를 패키지합니다.
  • IUITableViewDropDelegate – 삭제를 시도하고 완료할 때 정보를 처리합니다.

샘플에서 이러한 두 인터페이스는 모두 대리자 및 데이터 원본과 함께 클래스에서 구현 UITableViewController 됩니다. 메서드에 할당됩니다.ViewDidLoad

this.TableView.DragDelegate = this;
this.TableView.DropDelegate = this;

이러한 두 인터페이스에 필요한 최소 코드는 아래에 설명되어 있습니다.

테이블 뷰 끌기 대리자

테이블 뷰에서 행 끌기를 지원하는 데 필요한 유일한 방법은 .입니다GetItemsForBeginningDragSession. 사용자가 행을 끌기 시작하면 이 메서드가 호출됩니다.

구현은 다음과 같습니다. 끌어서 놓기 행과 연결된 데이터를 검색하고 인코딩하고 애플리케이션이 작업의 "삭제" 부분을 처리하는 방법을 결정하는 방법을 구성 NSItemProvider 합니다(예: 예제에서 데이터 형식 PlainText을 처리할 수 있는지 여부).

public UIDragItem[] GetItemsForBeginningDragSession (UITableView tableView,
  IUIDragSession session, NSIndexPath indexPath)
{
  // gets the 'information' to be dragged
  var placeName = model.PlaceNames[indexPath.Row];
  // convert to NSData representation
  var data = NSData.FromString(placeName, NSStringEncoding.UTF8);
  // create an NSItemProvider to describe the data
  var itemProvider = new NSItemProvider();
  itemProvider.RegisterDataRepresentation(UTType.PlainText,
                                NSItemProviderRepresentationVisibility.All,
                                (completion) =>
  {
    completion(data, null);
    return null;
  });
  // wrap in a UIDragItem
  return new UIDragItem[] { new UIDragItem(itemProvider) };
}

끌기 대리자의 선택적 메서드는 대상 앱에서 활용할 수 있는 여러 데이터 표현(예: 서식이 지정된 텍스트, 일반 텍스트, 드로잉의 벡터 및 비트맵 버전)을 제공하는 등 끌기 동작을 사용자 지정하기 위해 구현할 수 있는 많은 선택적 메서드가 있습니다. 동일한 앱 내에서 끌어서 놓을 때 사용할 사용자 지정 데이터 표현을 제공할 수도 있습니다.

테이블 뷰 놓기 대리자

끌어서 놓기 대리자의 메서드는 테이블 뷰 위에 끌기 작업이 발생하거나 그 위에 완료할 때 호출됩니다. 필요한 메서드는 데이터를 삭제할 수 있는지 여부와 삭제가 완료될 경우 수행되는 작업을 결정합니다.

  • CanHandleDropSession – 끌기가 진행 중이고 잠재적으로 애플리케이션에서 삭제되는 동안 이 메서드는 끌어서 놓는 데이터를 삭제할 수 있는지 여부를 결정합니다.
  • DropSessionDidUpdate – 끌기가 진행되는 동안 이 메서드를 호출하여 의도된 작업을 결정합니다. 끌어서 놓는 테이블 뷰의 정보, 끌기 세션 및 가능한 인덱스 경로를 모두 사용하여 사용자에게 제공된 동작 및 시각적 피드백을 확인할 수 있습니다.
  • PerformDrop – 사용자가 손가락을 떼어 놓기를 완료하면 이 메서드는 끌어서 놓는 데이터를 추출하고 테이블 뷰를 수정하여 새 행(또는 행)에 데이터를 추가합니다.

CanHandleDropSession

CanHandleDropSession 는 테이블 뷰에서 끌어서 놓는 데이터를 허용할 수 있는지 여부를 나타냅니다. 이 코드 조각 CanLoadObjects 에서는 이 테이블 뷰가 문자열 데이터를 허용할 수 있는지 확인하는 데 사용됩니다.

public bool CanHandleDropSession(UITableView tableView, IUIDropSession session)
{
  return session.CanLoadObjects(typeof(NSString));
}

DropSessionDidUpdate

DropSessionDidUpdate 끌기 작업이 진행되는 동안 메서드가 반복적으로 호출되어 사용자에게 시각적 신호를 제공합니다.

아래 HasActiveDrag 코드에서는 작업이 현재 테이블 뷰에서 시작되었는지 여부를 확인하는 데 사용됩니다. 이 경우 단일 행만 이동할 수 있습니다. 끌기가 다른 원본에서 온 경우 복사 작업이 표시됩니다.

public UITableViewDropProposal DropSessionDidUpdate(UITableView tableView, IUIDropSession session, NSIndexPath destinationIndexPath)
{
  // The UIDropOperation.Move operation is available only for dragging within a single app.
  if (tableView.HasActiveDrag)
  {
    if (session.Items.Length > 1)
    {
        return new UITableViewDropProposal(UIDropOperation.Cancel);
    } else {
        return new UITableViewDropProposal(UIDropOperation.Move, UITableViewDropIntent.InsertAtDestinationIndexPath);
    }
  } else {
    return new UITableViewDropProposal(UIDropOperation.Copy, UITableViewDropIntent.InsertAtDestinationIndexPath);
  }
}

놓기 작업은 , Move또는 Copy. 중 Cancel하나일 수 있습니다.

삭제 의도는 새 행을 삽입하거나 기존 행에 데이터를 추가/추가하는 것입니다.

PerformDrop

PerformDrop 메서드는 사용자가 작업을 완료하고 테이블 뷰 및 데이터 원본을 수정하여 삭제된 데이터를 반영할 때 호출됩니다.

public void PerformDrop(UITableView tableView, IUITableViewDropCoordinator coordinator)
{
  NSIndexPath indexPath, destinationIndexPath;
  if (coordinator.DestinationIndexPath != null)
  {
    indexPath = coordinator.DestinationIndexPath;
    destinationIndexPath = indexPath;
  }
  else
  {
    // Get last index path of table view
    var section = tableView.NumberOfSections() - 1;
    var row = tableView.NumberOfRowsInSection(section);
    destinationIndexPath = NSIndexPath.FromRowSection(row, section);
  }
  coordinator.Session.LoadObjects(typeof(NSString), (items) =>
  {
    // Consume drag items
    List<string> stringItems = new List<string>();
    foreach (var i in items)
    {
      var q = NSString.FromHandle(i.Handle);
      stringItems.Add(q.ToString());
    }
    var indexPaths = new List<NSIndexPath>();
    for (var j = 0; j < stringItems.Count; j++)
    {
      var indexPath1 = NSIndexPath.FromRowSection(destinationIndexPath.Row + j, destinationIndexPath.Section);
      model.AddItem(stringItems[j], indexPath1.Row);
      indexPaths.Add(indexPath1);
    }
    tableView.InsertRows(indexPaths.ToArray(), UITableViewRowAnimation.Automatic);
  });
}

큰 데이터 개체를 비동기적으로 로드하기 위해 추가 코드를 추가할 수 있습니다.