iOS Designer에서 테이블 작업

스토리보드는 iOS 애플리케이션을 만드는 WYSIWYG 방법이며 Mac 및 Windows의 Visual Studio 내에서 지원됩니다. Storyboards에 대한 자세한 내용은 스토리보드 소개 문서를 참조 하세요 . 스토리보드를 사용하면 표의 셀 레이아웃 을 편집할 수 있으므로 표와 셀을 사용한 개발이 간소화됩니다.

iOS 디자이너에서 테이블 뷰의 속성을 구성할 때 선택할 수 있는 셀 콘텐츠에는 동적 또는 정적 프로토타입 콘텐츠의 두 가지 유형이 있습니다.

동적 프로토타입 콘텐츠

UITableView 프로토타입 콘텐츠가 있는 A는 일반적으로 목록의 각 항목에 대해 프로토타입 셀(또는 둘 이상을 정의할 수 있는 셀)이 다시 사용되는 데이터 목록을 표시하기 위한 것입니다. 셀은 인스턴스화할 필요가 없으며 메서드의 UITableViewSource메서드를 GetView 호출 DequeueReusableCell 하여 메서드에서 가져옵니다.

정적 콘텐츠

UITableView정적 콘텐츠를 사용하여 테이블을 디자인 화면에서 바로 디자인할 수 있습니다. 셀을 표로 끌어와 속성을 변경하고 컨트롤을 추가하여 사용자 지정할 수 있습니다.

Storyboard 기반 앱 만들기

StoryboardTable 예제에는 Storyboard에서 두 가지 유형의 UITableView를 모두 사용하는 간단한 마스터-세부 앱이 포함되어 있습니다. 이 섹션의 re기본der는 완료되면 다음과 같이 표시되는 작은 할 일 목록 예제를 작성하는 방법을 설명합니다.

Example screens

사용자 인터페이스는 스토리보드를 사용하여 빌드되고 두 화면 모두 UITableView를 사용합니다. 기본 화면에서는 프로토타입 콘텐츠를 사용하여 행을 레이아웃하고, 세부 정보 화면은 정적 콘텐츠를 사용하여 사용자 지정 셀 레이아웃을 사용하여 데이터 입력 양식을 만듭니다.

연습

새 프로젝트를 사용하여 Visual Studio에서 새 솔루션 만들기... > 단일 보기 앱(C#)을 호출하고 StoryboardTables라고 합니다.

Create a new project dialog

솔루션은 일부 C# 파일 및 이미 만들어진 파일로 Main.storyboard 열립니다. 파일을 두 번 클릭하여 Main.storyboard iOS 디자이너에서 엽니다.

Storyboard 수정

스토리보드는 다음 세 단계로 편집됩니다.

  • 먼저 필요한 뷰 컨트롤러를 레이아웃하고 해당 속성을 설정합니다.
  • 둘째, 뷰에 개체를 끌어서 놓아 UI를 만듭니다.
  • 마지막으로, 각 보기에 필요한 UIKit 클래스를 추가하고 코드에서 참조할 수 있도록 다양한 컨트롤에 이름을 지정합니다.

스토리보드가 완료되면 코드를 추가하여 모든 작업을 수행할 수 있습니다.

뷰 컨트롤러 레이아웃

스토리보드의 첫 번째 변경 내용은 기존 세부 정보 보기를 삭제하고 UITableViewController로 바꾸는 것입니다. 다음 단계를 수행합니다.

  1. 보기 컨트롤러의 아래쪽에 있는 막대를 선택하고 삭제합니다.

  2. 탐색 컨트롤러와 테이블 뷰 컨트롤러도구 상자에서 스토리보드로 끌어다 놓습니다.

  3. 루트 뷰 컨트롤러에서 방금 추가된 두 번째 테이블 뷰 컨트롤러로 segue를 만듭니다. segue를 만들려면 Detail 셀에서 새로 추가된 UITableViewController로 Control+끌기를 실행합니다. Segue 선택 아래에 표시 옵션을 선택합니다.

  4. 만든 새 segue를 선택하고 코드에서 이 segue를 참조할 식별자를 제공합니다. Segue를 클릭하고 속성 패드에서 다음과 같이 식별자를 입력 TaskSegue 합니다.
    Naming segue in property panel

  5. 다음으로, 두 테이블 뷰를 선택하고 속성 패드를 사용하여 구성합니다. 보기 컨트롤러가 아닌 보기를 선택해야 합니다. 문서 개요를 사용하여 선택할 수 있습니다.

  6. 루트 뷰 컨트롤러를 콘텐츠로 변경합니다. 동적 프로토타입(디자인 화면의 보기에는 프로토타입 콘텐츠라는 레이블이 지정됨).

    Setting the Content property to dynamic prototypes

  7. UITableViewController를 Content: Static Cells으로 변경합니다.

  8. 새 UITableViewController에는 클래스 이름과 식별자 집합이 있어야 합니다. 뷰 컨트롤러를 선택하고 Properties Pad에서 클래스에 대한 TaskDetailViewController를 입력합니다. 그러면 Solution Pad에 새 TaskDetailViewController.cs 파일이 만들어집니다. 아래 예제와 같이 StoryboardID를 자세히 입력합니다. 나중에 C# 코드에서 이 보기를 로드하는 데 사용됩니다.

    Setting the Storyboard ID

  9. 이제 스토리보드 디자인 화면이 다음과 같이 표시됩니다(루트 뷰 컨트롤러의 탐색 항목 제목이 "Chore Board"로 변경됨).

    Design surface

UI 만들기

이제 뷰와 segue가 구성되었으므로 사용자 인터페이스 요소를 추가해야 합니다.

루트 뷰 컨트롤러

먼저 마스터 뷰 컨트롤러에서 프로토타입 셀을 선택하고 아래 그림과 같이 식별자를 작업 셀설정합니다. 코드의 뒷부분에서 이 UITableViewCell의 인스턴스를 검색하는 데 사용됩니다.

setting the cell identifier

다음으로, 아래 그림과 같이 새 작업을 추가하는 단추를 만들어야 합니다.

bar button item in the navigation bar

다음을 수행합니다.

  • 도구 상자에서 탐색 모음의 오른쪽에 있는 막대 단추 항목을 끕니다.
  • 속성 패드의 막대 단추 항목 아래에서 식별자: 추가(더하기 단추로 + 만들기)를 선택합니다.
  • 이후 단계에서 코드에서 식별할 수 있도록 이름을 지정합니다. 막대 단추 항목의 이름을 설정할 수 있도록 루트 뷰 컨트롤러에 클래스 이름(예 : ItemViewController)을 지정해야 합니다.

TaskDetail 뷰 컨트롤러

세부 정보 보기에는 더 많은 작업이 필요합니다. 표 보기 셀을 보기로 끌어온 다음 레이블, 텍스트 보기 및 단추로 채워야 합니다. 아래 스크린샷은 두 개의 섹션이 있는 완성된 UI를 보여줍니다. 한 섹션에는 셀 3개, 레이블 3개, 텍스트 필드 2개, 스위치 1개가 있으며, 두 번째 섹션에는 두 개의 단추가 있는 셀 하나가 있습니다.

detail view layout

전체 레이아웃을 빌드하는 단계는 다음과 같습니다.

테이블 보기를 선택하고 속성 패드엽니다. 다음 속성을 업데이트합니다.

  • 섹션: 2
  • 스타일: 그룹화됨
  • 구분 기호: 없음
  • 선택 영역: 선택 영역 없음

아래 그림과 같이 위쪽 섹션을 선택하고 속성 > 테이블 뷰 섹션에서 행을 3으로 변경합니다.

setting the top section to three rows

각 셀에 대해 Properties Pad를 열고 다음을 설정합니다.

  • 스타일: 사용자 지정
  • 식별자: 각 셀에 대한 고유 식별자 선택(예: "title", "notes", "done").
  • 필요한 컨트롤을 끌어 스크린샷에 표시된 레이아웃을 생성합니다(올바른 셀에 UILabel, UITextFieldUISwitch를 배치하고 레이블을 적절하게 설정합니다. 즉. 제목, 메모 및 완료).

두 번째 섹션에서 행을 1설정하고 셀의 아래쪽 크기 조정 핸들을 잡아 높이를 지정합니다.

  • 식별자: 고유 값(예: "save").

  • 배경 설정: 지우기.

  • 아래 그림과 같이 두 개의 단추를 셀로 끌어와 제목을 적절하게 설정합니다(예: 저장삭제).

    setting two buttons in the bottom section

이 시점에서 적응형 레이아웃을 보장하기 위해 셀 및 컨트롤에 제약 조건을 설정할 수도 있습니다.

UIKit 클래스 및 명명 컨트롤 추가

Storyboard를 만드는 몇 가지 마지막 단계가 있습니다. 먼저 각 컨트롤에 ID > 이름 아래에 이름을 지정해야 나중에 코드에서 사용할 수 있습니다. 이름을 다음과 같이 지정합니다.

  • Title UITextField : TitleText
  • 참고 UITextField : NotesText
  • UISwitch : DoneSwitch
  • UIButton 삭제: DeleteButton
  • UIButton 저장: SaveButton

코드 추가

작업의 다시 기본 작업은 Mac의 Visual Studio 또는 C#을 사용하여 Windows에서 수행됩니다. 코드에 사용되는 속성 이름은 위의 연습에서 설정한 이름을 반영합니다.

먼저 애플리케이션 전체에서 이러한 값을 사용할 수 있도록 ID, 이름, 메모 및 완료 부울 값을 가져오고 설정하는 방법을 제공하는 클래스를 만들려고 Chores 합니다.

Chores 클래스에서 다음 코드를 추가합니다.

public class Chores {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Notes { get; set; }
    public bool Done { get; set; }
  }

다음으로 , 에서 UITableViewSource상속되는 클래스를 만듭니 RootTableSource 다.

이 테이블 뷰와 Storyboard가 아닌 테이블 뷰의 차이점은 메서드가 GetViewtheDequeueReusableCell 을 인스턴스화할 필요가 없다는 점입니다. 메서드는 항상 프로토타입 셀의 인스턴스를 반환합니다(일치하는 식별자 포함).

아래 코드는 파일에서 가져옵니다 RootTableSource.cs .

public class RootTableSource : UITableViewSource
{
// there is NO database or storage of Tasks in this example, just an in-memory List<>
Chores[] tableItems;
string cellIdentifier = "taskcell"; // set in the Storyboard

    public RootTableSource(Chores[] items)
    {
        tableItems = items;
    }

public override nint RowsInSection(UITableView tableview, nint section)
{
  return tableItems.Length;
}

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
  // in a Storyboard, Dequeue will ALWAYS return a cell, 
  var cell = tableView.DequeueReusableCell(cellIdentifier);
  // now set the properties as normal
  cell.TextLabel.Text = tableItems[indexPath.Row].Name;
  if (tableItems[indexPath.Row].Done)
    cell.Accessory = UITableViewCellAccessory.Checkmark;
  else
    cell.Accessory = UITableViewCellAccessory.None;
  return cell;
}
public Chores GetItem(int id)
{
  return tableItems[id];
}

클래스를 RootTableSource 사용하려면 's 생성자에서 ItemViewController새 컬렉션을 만듭니다.

chores = new List<Chore> {
      new Chore {Name="Groceries", Notes="Buy bread, cheese, apples", Done=false},
      new Chore {Name="Devices", Notes="Buy Nexus, Galaxy, Droid", Done=false}
    };

ViewWillAppear 원본에 컬렉션을 전달하고 테이블 뷰에 할당합니다.

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);

    TableView.Source = new RootTableSource(chores.ToArray());
}

지금 앱을 실행하면 기본 화면이 로드되고 두 작업 목록이 표시됩니다. 작업이 터치되면 스토리보드에서 정의한 segue로 인해 세부 정보 화면이 표시되지만 현재 데이터가 표시되지는 않습니다.

segue에서 '매개 변수를 보내려면' 메서드를 재정의 PrepareForSegue 하고 (TaskDetailViewController이 예제의 경우) 속성을 DestinationViewController 설정합니다. 대상 뷰 컨트롤러 클래스는 인스턴스화되었지만 사용자에게 아직 표시되지 않습니다. 즉, 클래스에서 속성을 설정할 수 있지만 UI 컨트롤을 수정할 수는 없습니다.

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
    {
      if (segue.Identifier == "TaskSegue") { // set in Storyboard
        var navctlr = segue.DestinationViewController as TaskDetailViewController;
        if (navctlr != null) {
          var source = TableView.Source as RootTableSource;
          var rowPath = TableView.IndexPathForSelectedRow;
          var item = source.GetItem(rowPath.Row);
          navctlr.SetTask (this, item); // to be defined on the TaskDetailViewController
        }
      }
    }

메서드에서 TaskDetailViewControllerSetTask ViewWillAppear에서 참조할 수 있도록 해당 매개 변수를 속성에 할당합니다. 호출될 때 PrepareForSegue 존재하지 않을 수 있으므로 컨트롤 속성을 수정 SetTask 할 수 없습니다.

Chore currentTask {get;set;}
    public ItemViewController Delegate {get;set;} // will be used to Save, Delete later

public override void ViewWillAppear (bool animated)
    {
      base.ViewWillAppear (animated);
      TitleText.Text = currentTask.Name;
      NotesText.Text = currentTask.Notes;
      DoneSwitch.On = currentTask.Done;
    }

    // this will be called before the view is displayed
    public void SetTask (ItemViewController d, Chore task) {
      Delegate = d;
      currentTask = task;
    }

이제 segue가 세부 정보 화면을 열고 선택한 작업 정보를 표시합니다. 아쉽게도 저장삭제 단추에 대한 구현은 없습니다. 단추를 구현하기 전에 다음 메서드를 추가하여 ItemViewController.cs 기본 데이터를 업데이트하고 세부 정보 화면을 닫습니다.

public void SaveTask(Chores chore)
{
  var oldTask = chores.Find(t => t.Id == chore.Id);
        NavigationController.PopViewController(true);
}

public void DeleteTask(Chores chore)
{
  var oldTask = chores.Find(t => t.Id == chore.Id);
  chores.Remove(oldTask);
        NavigationController.PopViewController(true);
}

다음으로 단추의 TouchUpInside 이벤트 처리기를 TaskDetailViewController.cs 메서드ViewDidLoad 추가해야 합니다. Delegate 호출하고 ItemViewController 작업의 일부로 이 보기를 닫을 수 SaveTaskDeleteTask있도록 속성 참조가 특별히 만들어졌습니다.

SaveButton.TouchUpInside += (sender, e) => {
        currentTask.Name = TitleText.Text;
        currentTask.Notes = NotesText.Text;
        currentTask.Done = DoneSwitch.On;
        Delegate.SaveTask(currentTask);
      };

DeleteButton.TouchUpInside += (sender, e) => Delegate.DeleteTask(currentTask);

빌드할 기능의 마지막 기본 기능은 새 작업을 만드는 것입니다. ItemViewController.cs 새 작업을 만들고 세부 정보 보기를 여는 메서드를 추가합니다. 스토리보드에서 보기를 인스턴스화하려면 해당 뷰에 대한 메서드 Identifier 를 사용합니다InstantiateViewController. 이 예제에서는 '세부 정보'가 됩니다.

public void CreateTask () 
    {
      // first, add the task to the underlying data
      var newId = chores[chores.Count - 1].Id + 1;
      var newChore = new Chore{Id = newId};
      chores.Add (newChore);

      // then open the detail view to edit it
      var detail = Storyboard.InstantiateViewController("detail") as TaskDetailViewController;
      detail.SetTask (this, newChore);
      NavigationController.PushViewController (detail, true);
    }

마지막으로 ItemViewController.cs 메서드의 ViewDidLoad 탐색 모음에 있는 단추를 연결하여 호출합니다.

AddButton.Clicked += (sender, e) => CreateTask ();

Storyboard 예제를 완료합니다. 완성된 앱은 다음과 같습니다.

Finished app

이 예제에서는 다음을 보여 줍니다.

  • 데이터 목록을 표시하는 데 다시 사용하기 위해 셀이 정의되는 프로토타입 콘텐츠가 있는 테이블 만들기
  • 정적 콘텐츠가 있는 테이블을 만들어 입력 양식을 작성합니다. 여기에는 표 스타일 변경 및 섹션, 셀 및 UI 컨트롤 추가가 포함되었습니다.
  • segue를 만들고 메서드를 재정 PrepareForSegue 의하여 대상 뷰에 필요한 매개 변수를 알리는 방법입니다.
  • 메서드를 사용하여 스토리보드 뷰를 직접 로드합니다 Storyboard.InstantiateViewController .