• controller 이름 바꾸는 방법은 
image

안에서 controller 이름을 클릭후 변경가능

  • (간단하게 canvas의 요소를 controller코드상에서 outlet으로 연결하는 방법)

You’re going to make an outlet for this text field on the PlayerDetailsViewController using the Assistant Editor feature of Xcode. While still in the storyboard, open the Assistant Editor with the button from the toolbar (the one at the top right with two intertwining rings). It should automatically open on PlayerDetailsViewController.swift (if it doesn’t, use the jumpbar in the right hand split window to select PlayerDetailsViewController.swift).

Select the new text field and ctrl-drag(오르쪽클릭은 outlet,왼쪽클릭은 action) to the top of PlayersDetailViewController, just below the class definition. When the popup appears, name the new outlet nameTextField, and click Connect. Xcode will add the property to the PlayersDetailViewController class and connect it in the storyboard:

image

  • static cells: they only work in UITableViewController. Even though Interface Builder will let you add them to a table view inside a regular UIViewController, this won’t work during runtime.

  • (특정 요소를 first responder 로 만드는 방법 )

To avoid this, let a tap anywhere inside the row bring up the keyboard. OpenPlayerDetailsViewController.swift and add the following extension to the end of the file:

// MARK: - UITableViewDelegate
extension PlayerDetailsViewController {

  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.section == 0 {
      nameTextField.becomeFirstResponder()
    }
  }
}

If the user taps the first cell, the app should activate the text field. There’s only one cell in the section so you only need to test for the section index. Making the text field the first responder will automatically bring up the keyboard.

https://www.raywenderlich.com/160519/storyboards-tutorial-ios-10-getting-started-part-2

  • controller 이름 바꾸는 방법은 
image

안에서 controller 이름을 클릭후 변경가능

  • (간단하게 canvas의 요소를 controller코드상에서 outlet으로 연결하는 방법)

You’re going to make an outlet for this text field on the PlayerDetailsViewController using the Assistant Editor feature of Xcode. While still in the storyboard, open the Assistant Editor with the button from the toolbar (the one at the top right with two intertwining rings). It should automatically open on PlayerDetailsViewController.swift (if it doesn’t, use the jumpbar in the right hand split window to select PlayerDetailsViewController.swift).

Select the new text field and ctrl-drag(오르쪽클릭은 outlet,왼쪽클릭은 action) to the top of PlayersDetailViewController, just below the class definition. When the popup appears, name the new outlet nameTextField, and click Connect. Xcode will add the property to the PlayersDetailViewController class and connect it in the storyboard:

image

  • static cells: they only work in UITableViewController. Even though Interface Builder will let you add them to a table view inside a regular UIViewController, this won’t work during runtime.

  • (특정 요소를 first responder 로 만드는 방법 )

To avoid this, let a tap anywhere inside the row bring up the keyboard. OpenPlayerDetailsViewController.swift and add the following extension to the end of the file:

// MARK: - UITableViewDelegate
extension PlayerDetailsViewController {

  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.section == 0 {
      nameTextField.becomeFirstResponder()
    }
  }
}

If the user taps the first cell, the app should activate the text field. There’s only one cell in the section so you only need to test for the section index. Making the text field the first responder will automatically bring up the keyboard.

https://www.raywenderlich.com/160519/storyboards-tutorial-ios-10-getting-started-part-2

  • 예를 들어 segue에 있는 done button을 클릭해서 특정 데이터를 저장하고 modal형태의 창을 닫는 경우 두가지 이벤트를 이용할수 있다. 버튼에 연결되어있는 action과 segue가 닫히기 전에 이벤트를 전달 받는 hook 포인트 prepare 가 있다. 

https://www.raywenderlich.com/160519/storyboards-tutorial-ios-10-getting-started-part-2

original source : http://www.androiddocs.com/training/wearables/ui/lists.html

Creating Lists

Lists let users select an item from a set of choices easily on wearable devices.

The Wearable UI Library includes the WearableListView class .

To create a list in your Android Wear apps:

  1. Add a WearableListView element to your activity’s layout definition.
  2. Create a custom layout implementation for your list items.
  3. Use this implementation to create a layout definition file for your list items.
  4. Create an adapter to populate the list.
  5. Assign the adapter to the WearableListView element

Add a List View

<android.support.wearable.view.BoxInsetLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:background="@drawable/robot_background"
   android:layout_height="match_parent"
   android:layout_width="match_parent">

   <FrameLayout
       android:id="@+id/frame_layout"
       android:layout_height="match_parent"
       android:layout_width="match_parent"
       app:layout_box="left|bottom|right">

       <android.support.wearable.view.WearableListView
           android:id="@+id/wearable_list"
           android:layout_height="match_parent"
           android:layout_width="match_parent">
       </android.support.wearable.view.WearableListView>
   </FrameLayout>
</android.support.wearable.view.BoxInsetLayout>



Create a Layout Implementation for List Items

This layout also implements the methods in the WearableListView.OnCenterProximityListener interface to change the color of the item’s icon and fade the text in response to events from WearableListView as the user scrolls through the list.

public class WearableListItemLayout extends LinearLayout
            implements WearableListView.OnCenterProximityListener {

   private ImageView mCircle;
   private TextView mName;

   private final float mFadedTextAlpha;
   private final int mFadedCircleColor;
   private final int mChosenCircleColor;

   public WearableListItemLayout(Context context) {
       this(context, null);
   }

   public WearableListItemLayout(Context context, AttributeSet attrs) {
       this(context, attrs, 0);
   }

   public WearableListItemLayout(Context context, AttributeSet attrs,
                                 int defStyle) {
       super(context, attrs, defStyle);

       mFadedTextAlpha = getResources()
                        .getInteger(R.integer.action_text_faded_alpha) / 100f;
       mFadedCircleColor = getResources().getColor(R.color.grey);
       mChosenCircleColor = getResources().getColor(R.color.blue);
   }

   // Get references to the icon and text in the item layout definition
   @Override
   protected void onFinishInflate() {
       super.onFinishInflate();
       // These are defined in the layout file for list items
       // (see next section)
       mCircle = (ImageView) findViewById(R.id.circle);
       mName = (TextView) findViewById(R.id.name);
   }

   @Override
   public void onCenterPosition(boolean animate) {
       mName.setAlpha(1f);
       ((GradientDrawable) mCircle.getDrawable()).setColor(mChosenCircleColor);
   }

   @Override
   public void onNonCenterPosition(boolean animate) {
       ((GradientDrawable) mCircle.getDrawable()).setColor(mFadedCircleColor);
       mName.setAlpha(mFadedTextAlpha);
   }
}



Create a Layout Definition for Items

res/layout/list_item.xml

<com.example.android.support.wearable.notifications.WearableListItemLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:gravity="center_vertical"
   android:layout_width="match_parent"
   android:layout_height="80dp">
   <ImageView
       android:id="@+id/circle"
       android:layout_height="20dp"
       android:layout_margin="16dp"
       android:layout_width="20dp"
       android:src="@drawable/wl_circle"/>
   <TextView
       android:id="@+id/name"
       android:gravity="center_vertical|left"
       android:layout_width="wrap_content"
       android:layout_marginRight="16dp"
       android:layout_height="match_parent"
       android:fontFamily="sans-serif-condensed-light"
       android:lineSpacingExtra="-4sp"
       android:textColor="@color/text_color"
       android:textSize="16sp"/>
</com.example.android.support.wearable.notifications.WearableListItemLayout>



Create an Adapter to Populate the List

private static final class Adapter extends WearableListView.Adapter {
   private String[] mDataset;
   private final Context mContext;
   private final LayoutInflater mInflater;

   // Provide a suitable constructor (depends on the kind of dataset)
   public Adapter(Context context, String[] dataset) {
       mContext = context;
       mInflater = LayoutInflater.from(context);
       mDataset = dataset;
   }

   // Provide a reference to the type of views you're using
   public static class ItemViewHolder extends WearableListView.ViewHolder {
       private TextView textView;
       public ItemViewHolder(View itemView) {
           super(itemView);
           // find the text view within the custom item's layout
           textView = (TextView) itemView.findViewById(R.id.name);
       }
   }

   // Create new views for list items
   // (invoked by the WearableListView's layout manager)
   @Override
   public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                         int viewType) {
       // Inflate our custom layout for list items
       return new ItemViewHolder(mInflater.inflate(R.layout.list_item, null));
   }

   // Replace the contents of a list item
   // Instead of creating new views, the list tries to recycle existing ones
   // (invoked by the WearableListView's layout manager)
   @Override
   public void onBindViewHolder(WearableListView.ViewHolder holder,
                                int position) {
       // retrieve the text view
       ItemViewHolder itemHolder = (ItemViewHolder) holder;
       TextView view = itemHolder.textView;
       // replace text contents
       view.setText(mDataset[position]);
       // replace list item's metadata
       holder.itemView.setTag(position);
   }

   // Return the size of your dataset
   // (invoked by the WearableListView's layout manager)
   @Override
   public int getItemCount() {
       return mDataset.length;
   }
}



Associate the Adapter and Set a Click Listener

public class WearActivity extends Activity
                         implements WearableListView.ClickListener {

   // Sample dataset for the list
   String[] elements = { "List Item 1", "List Item 2", ... };

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.my_list_activity);

       // Get the list component from the layout of the activity
       WearableListView listView =
           (WearableListView) findViewById(R.id.wearable_list);

       // Assign an adapter to the list
       listView.setAdapter(new Adapter(this, elements));

       // Set a click listener
       listView.setClickListener(this);
   }

   // WearableListView click listener
   @Override
   public void onClick(WearableListView.ViewHolder v) {
       Integer tag = (Integer) v.itemView.getTag();
       // use this data to complete some action ...
   }

   @Override
   public void onTopEmptyRegionClick() {
   }
}

original source : http://www.androiddocs.com/training/wearables/ui/lists.html

Creating Lists

Lists let users select an item from a set of choices easily on wearable devices.

The Wearable UI Library includes the WearableListView class .

To create a list in your Android Wear apps:

  1. Add a WearableListView element to your activity’s layout definition.
  2. Create a custom layout implementation for your list items.
  3. Use this implementation to create a layout definition file for your list items.
  4. Create an adapter to populate the list.
  5. Assign the adapter to the WearableListView element

Add a List View

<android.support.wearable.view.BoxInsetLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:background="@drawable/robot_background"
   android:layout_height="match_parent"
   android:layout_width="match_parent">

   <FrameLayout
       android:id="@+id/frame_layout"
       android:layout_height="match_parent"
       android:layout_width="match_parent"
       app:layout_box="left|bottom|right">

       <android.support.wearable.view.WearableListView
           android:id="@+id/wearable_list"
           android:layout_height="match_parent"
           android:layout_width="match_parent">
       </android.support.wearable.view.WearableListView>
   </FrameLayout>
</android.support.wearable.view.BoxInsetLayout>



Create a Layout Implementation for List Items

This layout also implements the methods in the WearableListView.OnCenterProximityListener interface to change the color of the item’s icon and fade the text in response to events from WearableListView as the user scrolls through the list.

public class WearableListItemLayout extends LinearLayout
            implements WearableListView.OnCenterProximityListener {

   private ImageView mCircle;
   private TextView mName;

   private final float mFadedTextAlpha;
   private final int mFadedCircleColor;
   private final int mChosenCircleColor;

   public WearableListItemLayout(Context context) {
       this(context, null);
   }

   public WearableListItemLayout(Context context, AttributeSet attrs) {
       this(context, attrs, 0);
   }

   public WearableListItemLayout(Context context, AttributeSet attrs,
                                 int defStyle) {
       super(context, attrs, defStyle);

       mFadedTextAlpha = getResources()
                        .getInteger(R.integer.action_text_faded_alpha) / 100f;
       mFadedCircleColor = getResources().getColor(R.color.grey);
       mChosenCircleColor = getResources().getColor(R.color.blue);
   }

   // Get references to the icon and text in the item layout definition
   @Override
   protected void onFinishInflate() {
       super.onFinishInflate();
       // These are defined in the layout file for list items
       // (see next section)
       mCircle = (ImageView) findViewById(R.id.circle);
       mName = (TextView) findViewById(R.id.name);
   }

   @Override
   public void onCenterPosition(boolean animate) {
       mName.setAlpha(1f);
       ((GradientDrawable) mCircle.getDrawable()).setColor(mChosenCircleColor);
   }

   @Override
   public void onNonCenterPosition(boolean animate) {
       ((GradientDrawable) mCircle.getDrawable()).setColor(mFadedCircleColor);
       mName.setAlpha(mFadedTextAlpha);
   }
}



Create a Layout Definition for Items

res/layout/list_item.xml

<com.example.android.support.wearable.notifications.WearableListItemLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:gravity="center_vertical"
   android:layout_width="match_parent"
   android:layout_height="80dp">
   <ImageView
       android:id="@+id/circle"
       android:layout_height="20dp"
       android:layout_margin="16dp"
       android:layout_width="20dp"
       android:src="@drawable/wl_circle"/>
   <TextView
       android:id="@+id/name"
       android:gravity="center_vertical|left"
       android:layout_width="wrap_content"
       android:layout_marginRight="16dp"
       android:layout_height="match_parent"
       android:fontFamily="sans-serif-condensed-light"
       android:lineSpacingExtra="-4sp"
       android:textColor="@color/text_color"
       android:textSize="16sp"/>
</com.example.android.support.wearable.notifications.WearableListItemLayout>



Create an Adapter to Populate the List

private static final class Adapter extends WearableListView.Adapter {
   private String[] mDataset;
   private final Context mContext;
   private final LayoutInflater mInflater;

   // Provide a suitable constructor (depends on the kind of dataset)
   public Adapter(Context context, String[] dataset) {
       mContext = context;
       mInflater = LayoutInflater.from(context);
       mDataset = dataset;
   }

   // Provide a reference to the type of views you're using
   public static class ItemViewHolder extends WearableListView.ViewHolder {
       private TextView textView;
       public ItemViewHolder(View itemView) {
           super(itemView);
           // find the text view within the custom item's layout
           textView = (TextView) itemView.findViewById(R.id.name);
       }
   }

   // Create new views for list items
   // (invoked by the WearableListView's layout manager)
   @Override
   public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                         int viewType) {
       // Inflate our custom layout for list items
       return new ItemViewHolder(mInflater.inflate(R.layout.list_item, null));
   }

   // Replace the contents of a list item
   // Instead of creating new views, the list tries to recycle existing ones
   // (invoked by the WearableListView's layout manager)
   @Override
   public void onBindViewHolder(WearableListView.ViewHolder holder,
                                int position) {
       // retrieve the text view
       ItemViewHolder itemHolder = (ItemViewHolder) holder;
       TextView view = itemHolder.textView;
       // replace text contents
       view.setText(mDataset[position]);
       // replace list item's metadata
       holder.itemView.setTag(position);
   }

   // Return the size of your dataset
   // (invoked by the WearableListView's layout manager)
   @Override
   public int getItemCount() {
       return mDataset.length;
   }
}



Associate the Adapter and Set a Click Listener

public class WearActivity extends Activity
                         implements WearableListView.ClickListener {

   // Sample dataset for the list
   String[] elements = { "List Item 1", "List Item 2", ... };

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.my_list_activity);

       // Get the list component from the layout of the activity
       WearableListView listView =
           (WearableListView) findViewById(R.id.wearable_list);

       // Assign an adapter to the list
       listView.setAdapter(new Adapter(this, elements));

       // Set a click listener
       listView.setClickListener(this);
   }

   // WearableListView click listener
   @Override
   public void onClick(WearableListView.ViewHolder v) {
       Integer tag = (Integer) v.itemView.getTag();
       // use this data to complete some action ...
   }

   @Override
   public void onTopEmptyRegionClick() {
   }
}

original source : http://www.androiddocs.com/training/wearables/apps/voice.html

사용자로부터 음성으로 data입력을 받으려는 경우

Obtaining Free-form Speech Input

In addition to using voice actions to launch activities, you can also call the system’s built-in Speech Recognizer activity to obtain speech input from users. This is useful to obtain input from users and then process it, such as doing a search or sending it as a message.

In your app, you call

startActivityForResult()

using the

ACTION_RECOGNIZE_SPEECH

action. This starts the speech recognition activity, and you can then handle the result in

onActivityResult()

.

private static final int SPEECH_REQUEST_CODE = 0;

// Create an intent that can start the Speech Recognizer activity
private void displaySpeechRecognizer() {
   Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
   intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
           RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// Start the activity, the intent will be populated with the speech text
   startActivityForResult(intent, SPEECH_REQUEST_CODE);
}

// This callback is invoked when the Speech Recognizer returns.
// This is where you process the intent and extract the speech text from the intent.
@Override
protected void onActivityResult(int requestCode, int resultCode,
       Intent data) {
   if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {
       List<String> results = data.getStringArrayListExtra(
               RecognizerIntent.EXTRA_RESULTS);
       String spokenText = results.get(0);
       // Do something with spokenText
   }
   super.onActivityResult(requestCode, resultCode, data);

original source : http://www.androiddocs.com/training/wearables/apps/voice.html

사용자로부터 음성으로 data입력을 받으려는 경우

Obtaining Free-form Speech Input

In addition to using voice actions to launch activities, you can also call the system’s built-in Speech Recognizer activity to obtain speech input from users. This is useful to obtain input from users and then process it, such as doing a search or sending it as a message.

In your app, you call

startActivityForResult()

using the

ACTION_RECOGNIZE_SPEECH

action. This starts the speech recognition activity, and you can then handle the result in

onActivityResult()

.

private static final int SPEECH_REQUEST_CODE = 0;

// Create an intent that can start the Speech Recognizer activity
private void displaySpeechRecognizer() {
   Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
   intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
           RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// Start the activity, the intent will be populated with the speech text
   startActivityForResult(intent, SPEECH_REQUEST_CODE);
}

// This callback is invoked when the Speech Recognizer returns.
// This is where you process the intent and extract the speech text from the intent.
@Override
protected void onActivityResult(int requestCode, int resultCode,
       Intent data) {
   if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {
       List<String> results = data.getStringArrayListExtra(
               RecognizerIntent.EXTRA_RESULTS);
       String spokenText = results.get(0);
       // Do something with spokenText
   }
   super.onActivityResult(requestCode, resultCode, data);

original source: http://www.androiddocs.com/training/wearables/notifications/pages.html

Adding Pages to a Notification

additional pages appear immediately to the right of the main notification card.

To create a notification with multiple pages:

  1. Create the main notification (the first page) with NotificationCompat.Builder, in the way you’d like the notification to appear on a handset.
  2. Create the additional pages for the wearable with NotificationCompat.Builder.
  3. Apply the pages to the main notification with the addPage() method or add multiple pages in a Collectionwith the addPages() method.

// Create builder for the main notification
NotificationCompat.Builder notificationBuilder =
       new NotificationCompat.Builder(this)
       .setSmallIcon(R.drawable.new_message)
       .setContentTitle("Page 1")
       .setContentText("Short message")
       .setContentIntent(viewPendingIntent);

// Create a big text style for the second page
BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
secondPageStyle.setBigContentTitle("Page 2")
              .bigText("A lot of text...");

// Create second page notification
Notification secondPageNotification =
       new NotificationCompat.Builder(this)
       .setStyle(secondPageStyle)
       .build();

// Extend the notification builder with the second page
Notification notification = notificationBuilder
       .extend(new NotificationCompat.WearableExtender()
               .addPage(secondPageNotification))
       .build();

// Issue the notification
notificationManager =
       NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notification);