зеркало из https://github.com/xamarin/ios-samples.git
597 строки
22 KiB
C#
597 строки
22 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using CoreGraphics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Foundation;
|
|
using UIKit;
|
|
using ObjCRuntime;
|
|
using CoreText;
|
|
|
|
namespace SimpleTextInput
|
|
{
|
|
[Adopts ("UITextInput")]
|
|
[Adopts ("UIKeyInput")]
|
|
[Adopts ("UITextInputTraits")]
|
|
[Register ("EditableCoreTextView")]
|
|
public class EditableCoreTextView : UIView
|
|
{
|
|
StringBuilder text = new StringBuilder ();
|
|
IUITextInputTokenizer tokenizer;
|
|
SimpleCoreTextView textView;
|
|
NSDictionary markedTextStyle;
|
|
IUITextInputDelegate inputDelegate;
|
|
|
|
public delegate void ViewWillEditDelegate (EditableCoreTextView editableCoreTextView);
|
|
public event ViewWillEditDelegate ViewWillEdit;
|
|
|
|
public EditableCoreTextView (CGRect frame)
|
|
: base (frame)
|
|
{
|
|
// Add tap gesture recognizer to let the user enter editing mode
|
|
UITapGestureRecognizer tap = new UITapGestureRecognizer (Tap) {
|
|
ShouldReceiveTouch = delegate(UIGestureRecognizer recognizer, UITouch touch) {
|
|
// If gesture touch occurs in our view, we want to handle it
|
|
return touch.View == this;
|
|
}
|
|
};
|
|
AddGestureRecognizer (tap);
|
|
|
|
// Create our tokenizer and text storage
|
|
tokenizer = new UITextInputStringTokenizer ();
|
|
|
|
// Create and set up our SimpleCoreTextView that will do the drawing
|
|
textView = new SimpleCoreTextView (Bounds.Inset (5, 5));
|
|
textView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
|
|
UserInteractionEnabled = true;
|
|
AutosizesSubviews = true;
|
|
AddSubview (textView);
|
|
textView.Text = string.Empty;
|
|
textView.UserInteractionEnabled = false;
|
|
}
|
|
|
|
protected override void Dispose (bool disposing)
|
|
{
|
|
markedTextStyle = null;
|
|
tokenizer = null;
|
|
text = null;
|
|
textView = null;
|
|
base.Dispose (disposing);
|
|
}
|
|
|
|
#region Custom user interaction
|
|
|
|
// UIResponder protocol override - our view can become first responder to
|
|
// receive user text input
|
|
public override bool CanBecomeFirstResponder {
|
|
get {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// UIResponder protocol override - called when our view is being asked to resign
|
|
// first responder state (in this sample by using the "Done" button)
|
|
public override bool ResignFirstResponder ()
|
|
{
|
|
textView.IsEditing = false;
|
|
return base.ResignFirstResponder ();
|
|
}
|
|
|
|
// Our tap gesture recognizer selector that enters editing mode, or if already
|
|
// in editing mode, updates the text insertion point
|
|
[Export ("Tap:")]
|
|
public void Tap (UITapGestureRecognizer tap)
|
|
{
|
|
if (!IsFirstResponder) {
|
|
// Inform controller that we're about to enter editing mode
|
|
if (ViewWillEdit != null)
|
|
ViewWillEdit (this);
|
|
// Flag that underlying SimpleCoreTextView is now in edit mode
|
|
textView.IsEditing = true;
|
|
// Become first responder state (which shows software keyboard, if applicable)
|
|
BecomeFirstResponder ();
|
|
} else {
|
|
// Already in editing mode, set insertion point (via selectedTextRange)
|
|
// Find and update insertion point in underlying SimpleCoreTextView
|
|
int index = textView.ClosestIndex (tap.LocationInView (textView));
|
|
textView.MarkedTextRange = new NSRange (NSRange.NotFound, 0);
|
|
textView.SelectedTextRange = new NSRange (index, 0);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region UITextInput methods
|
|
[Export ("inputDelegate")]
|
|
public IUITextInputDelegate InputDelegate {
|
|
get {
|
|
return inputDelegate;
|
|
}
|
|
set {
|
|
inputDelegate = value;
|
|
}
|
|
}
|
|
|
|
[Export ("markedTextStyle")]
|
|
public NSDictionary MarkedTextStyle {
|
|
get {
|
|
return markedTextStyle;
|
|
}
|
|
set {
|
|
markedTextStyle = value;
|
|
}
|
|
}
|
|
|
|
#region UITextInput - Replacing and Returning Text
|
|
// UITextInput required method - called by text system to get the string for
|
|
// a given range in the text storage
|
|
[Export ("textInRange:")]
|
|
string TextInRange (UITextRange range)
|
|
{
|
|
IndexedRange r = (IndexedRange) range;
|
|
return text.ToString ().Substring ((int)r.Range.Location, (int)r.Range.Length);
|
|
}
|
|
|
|
// UITextInput required method - called by text system to replace the given
|
|
// text storage range with new text
|
|
[Export ("replaceRange:withText:")]
|
|
void ReplaceRange (UITextRange range, string text)
|
|
{
|
|
IndexedRange r = (IndexedRange) range;
|
|
NSRange selectedNSRange = textView.SelectedTextRange;
|
|
// Determine if replaced range intersects current selection range
|
|
// and update selection range if so.
|
|
if (r.Range.Location + r.Range.Length <= selectedNSRange.Location) {
|
|
// This is the easy case.
|
|
selectedNSRange.Location -= (r.Range.Length - text.Length);
|
|
} else {
|
|
// Need to also deal with overlapping ranges. Not addressed
|
|
// in this simplified sample.
|
|
}
|
|
|
|
// Now replace characters in text storage
|
|
this.text.Remove ((int)r.Range.Location, (int)r.Range.Length);
|
|
this.text.Insert ((int)r.Range.Location, text);
|
|
|
|
// Update underlying SimpleCoreTextView
|
|
textView.Text = this.text.ToString ();
|
|
textView.SelectedTextRange = selectedNSRange;
|
|
}
|
|
#endregion
|
|
#region UITextInput - Working with Marked and Selected Text
|
|
|
|
// UITextInput selectedTextRange property accessor overrides
|
|
// (access/update underlaying SimpleCoreTextView)
|
|
[Export ("selectedTextRange")]
|
|
IndexedRange SelectedTextRange {
|
|
get {
|
|
return IndexedRange.GetRange (textView.SelectedTextRange);
|
|
}
|
|
set {
|
|
textView.SelectedTextRange = value.Range;
|
|
}
|
|
}
|
|
|
|
// UITextInput markedTextRange property accessor overrides
|
|
// (access/update underlaying SimpleCoreTextView)
|
|
[Export ("markedTextRange")]
|
|
IndexedRange MarkedTextRange {
|
|
get {
|
|
return IndexedRange.GetRange (textView.MarkedTextRange);
|
|
}
|
|
}
|
|
|
|
// UITextInput required method - Insert the provided text and marks it to indicate
|
|
// that it is part of an active input session.
|
|
[Export ("setMarkedText:selectedRange:")]
|
|
void SetMarkedText (string markedText, NSRange selectedRange)
|
|
{
|
|
NSRange selectedNSRange = textView.SelectedTextRange;
|
|
NSRange markedTextRange = textView.MarkedTextRange;
|
|
|
|
if (markedText == null)
|
|
markedText = string.Empty;
|
|
|
|
if (markedTextRange.Location != NSRange.NotFound) {
|
|
// Replace characters in text storage and update markedText range length
|
|
text.Remove ((int)markedTextRange.Location, (int)markedTextRange.Length);
|
|
text.Insert ((int)markedTextRange.Location, markedText);
|
|
markedTextRange.Length = markedText.Length;
|
|
} else if (selectedNSRange.Length > 0) {
|
|
// There currently isn't a marked text range, but there is a selected range,
|
|
// so replace text storage at selected range and update markedTextRange.
|
|
text.Remove ((int)selectedNSRange.Location, (int)selectedNSRange.Length);
|
|
text.Insert ((int)selectedNSRange.Location, markedText);
|
|
markedTextRange.Location = selectedNSRange.Location;
|
|
markedTextRange.Length = markedText.Length;
|
|
} else {
|
|
// There currently isn't marked or selected text ranges, so just insert
|
|
// given text into storage and update markedTextRange.
|
|
text.Insert ((int)selectedNSRange.Location, markedText);
|
|
markedTextRange.Location = selectedNSRange.Location;
|
|
markedTextRange.Length = markedText.Length;
|
|
}
|
|
|
|
// Updated selected text range and underlying SimpleCoreTextView
|
|
selectedNSRange = new NSRange (selectedRange.Location + markedTextRange.Location, selectedRange.Length);
|
|
textView.Text = text.ToString ();
|
|
textView.MarkedTextRange = markedTextRange;
|
|
textView.SelectedTextRange = selectedNSRange;
|
|
}
|
|
|
|
// UITextInput required method - Unmark the currently marked text.
|
|
[Export ("unmarkText")]
|
|
void UnmarkText ()
|
|
{
|
|
NSRange markedTextRange = textView.MarkedTextRange;
|
|
|
|
if (markedTextRange.Location == NSRange.NotFound)
|
|
return;
|
|
|
|
// unmark the underlying SimpleCoreTextView.markedTextRange
|
|
markedTextRange.Location = NSRange.NotFound;
|
|
textView.MarkedTextRange = markedTextRange;
|
|
|
|
}
|
|
#endregion
|
|
#region UITextInput - Computing Text Ranges and Text Positions
|
|
|
|
// UITextInput beginningOfDocument property accessor override
|
|
[Export ("beginningOfDocument")]
|
|
IndexedPosition BeginningOfDocument {
|
|
get {
|
|
// For this sample, the document always starts at index 0 and is the full
|
|
// length of the text storage
|
|
return IndexedPosition.GetPosition (0);
|
|
}
|
|
}
|
|
|
|
// UITextInput endOfDocument property accessor override
|
|
[Export ("endOfDocument")]
|
|
IndexedPosition EndOfDocument {
|
|
get {
|
|
// For this sample, the document always starts at index 0 and is the full
|
|
// length of the text storage
|
|
return IndexedPosition.GetPosition (text.Length);
|
|
}
|
|
}
|
|
|
|
// UITextInput protocol required method - Return the range between two text positions
|
|
// using our implementation of UITextRange
|
|
[Export ("textRangeFromPosition:toPosition:")]
|
|
IndexedRange GetTextRange (UITextPosition fromPosition, UITextPosition toPosition)
|
|
{
|
|
// Generate IndexedPosition instances that wrap the to and from ranges
|
|
IndexedPosition @from = (IndexedPosition) fromPosition;
|
|
IndexedPosition @to = (IndexedPosition) toPosition;
|
|
NSRange range = new NSRange (Math.Min (@from.Index, @to.Index), Math.Abs (to.Index - @from.Index));
|
|
return IndexedRange.GetRange (range);
|
|
}
|
|
|
|
// UITextInput protocol required method - Returns the text position at a given offset
|
|
// from another text position using our implementation of UITextPosition
|
|
[Export ("positionFromPosition:offset:")]
|
|
IndexedPosition GetPosition (UITextPosition position, int offset)
|
|
{
|
|
// Generate IndexedPosition instance, and increment index by offset
|
|
IndexedPosition pos = (IndexedPosition) position;
|
|
int end = pos.Index + offset;
|
|
// Verify position is valid in document
|
|
if (end > text.Length || end < 0)
|
|
return null;
|
|
|
|
return IndexedPosition.GetPosition (end);
|
|
}
|
|
|
|
// UITextInput protocol required method - Returns the text position at a given offset
|
|
// in a specified direction from another text position using our implementation of
|
|
// UITextPosition.
|
|
[Export ("positionFromPosition:inDirection:offset:")]
|
|
IndexedPosition GetPosition (UITextPosition position, UITextLayoutDirection direction, int offset)
|
|
{
|
|
// Note that this sample assumes LTR text direction
|
|
IndexedPosition pos = (IndexedPosition) position;
|
|
int newPos = pos.Index;
|
|
|
|
switch (direction) {
|
|
case UITextLayoutDirection.Right:
|
|
newPos += offset;
|
|
break;
|
|
case UITextLayoutDirection.Left:
|
|
newPos -= offset;
|
|
break;
|
|
case UITextLayoutDirection.Up:
|
|
case UITextLayoutDirection.Down:
|
|
// This sample does not support vertical text directions
|
|
break;
|
|
}
|
|
|
|
// Verify new position valid in document
|
|
|
|
if (newPos < 0)
|
|
newPos = 0;
|
|
|
|
if (newPos > text.Length)
|
|
newPos = text.Length;
|
|
|
|
return IndexedPosition.GetPosition (newPos);
|
|
}
|
|
#endregion
|
|
#region UITextInput - Evaluating Text Positions
|
|
|
|
// UITextInput protocol required method - Return how one text position compares to another
|
|
// text position.
|
|
[Export ("comparePosition:toPosition:")]
|
|
NSComparisonResult ComparePosition (UITextPosition position, UITextPosition other)
|
|
{
|
|
IndexedPosition pos = (IndexedPosition) position;
|
|
IndexedPosition o = (IndexedPosition) other;
|
|
|
|
// For this sample, we simply compare position index values
|
|
if (pos.Index == o.Index) {
|
|
return NSComparisonResult.Same;
|
|
} else if (pos.Index < o.Index) {
|
|
return NSComparisonResult.Ascending;
|
|
} else {
|
|
return NSComparisonResult.Descending;
|
|
}
|
|
}
|
|
|
|
// UITextInput protocol required method - Return the number of visible characters
|
|
// between one text position and another text position.
|
|
[Export ("offsetFromPosition:toPosition:")]
|
|
int GetOffset (IndexedPosition @from, IndexedPosition toPosition)
|
|
{
|
|
return @from.Index - toPosition.Index;
|
|
}
|
|
#endregion
|
|
#region UITextInput - Text Input Delegate and Text Input Tokenizer
|
|
|
|
// UITextInput tokenizer property accessor override
|
|
//
|
|
// An input tokenizer is an object that provides information about the granularity
|
|
// of text units by implementing the UITextInputTokenizer protocol. Standard units
|
|
// of granularity include characters, words, lines, and paragraphs. In most cases,
|
|
// you may lazily create and assign an instance of a subclass of
|
|
// UITextInputStringTokenizer for this purpose, as this sample does. If you require
|
|
// different behavior than this system-provided tokenizer, you can create a custom
|
|
// tokenizer that adopts the UITextInputTokenizer protocol.
|
|
[Export ("tokenizer")]
|
|
IUITextInputTokenizer Tokenizer {
|
|
get {
|
|
return tokenizer;
|
|
}
|
|
}
|
|
#endregion
|
|
#region UITextInput - Text Layout, writing direction and position related methods
|
|
// UITextInput protocol method - Return the text position that is at the farthest
|
|
// extent in a given layout direction within a range of text.
|
|
[Export ("positionWithinRange:farthestInDirection:")]
|
|
IndexedPosition GetPosition (UITextRange range, UITextLayoutDirection direction)
|
|
{
|
|
// Note that this sample assumes LTR text direction
|
|
IndexedRange r = (IndexedRange) range;
|
|
int pos = (int)r.Range.Location;
|
|
|
|
// For this sample, we just return the extent of the given range if the
|
|
// given direction is "forward" in a LTR context (UITextLayoutDirectionRight
|
|
// or UITextLayoutDirectionDown), otherwise we return just the range position
|
|
switch (direction) {
|
|
case UITextLayoutDirection.Up:
|
|
case UITextLayoutDirection.Left:
|
|
pos = (int)r.Range.Location;
|
|
break;
|
|
case UITextLayoutDirection.Right:
|
|
case UITextLayoutDirection.Down:
|
|
pos = (int)(r.Range.Location + r.Range.Length);
|
|
break;
|
|
}
|
|
|
|
// Return text position using our UITextPosition implementation.
|
|
// Note that position is not currently checked against document range.
|
|
return IndexedPosition.GetPosition (pos);
|
|
}
|
|
|
|
// UITextInput protocol required method - Return a text range from a given text position
|
|
// to its farthest extent in a certain direction of layout.
|
|
[Export ("characterRangeByExtendingPosition:inDirection:")]
|
|
IndexedRange GetCharacterRange (UITextPosition position, UITextLayoutDirection direction)
|
|
{
|
|
// Note that this sample assumes LTR text direction
|
|
IndexedPosition pos = (IndexedPosition) position;
|
|
NSRange result = new NSRange (pos.Index, 1);
|
|
|
|
switch (direction) {
|
|
case UITextLayoutDirection.Up:
|
|
case UITextLayoutDirection.Left:
|
|
result = new NSRange (pos.Index - 1, 1);
|
|
break;
|
|
case UITextLayoutDirection.Right:
|
|
case UITextLayoutDirection.Down:
|
|
result = new NSRange (pos.Index, 1);
|
|
break;
|
|
}
|
|
|
|
// Return range using our UITextRange implementation
|
|
// Note that range is not currently checked against document range.
|
|
return IndexedRange.GetRange (result);
|
|
}
|
|
|
|
// UITextInput protocol required method - Return the base writing direction for
|
|
// a position in the text going in a specified text direction.
|
|
[Export ("baseWritingDirectionForPosition:inDirection:")]
|
|
UITextWritingDirection GetBaseWritingDirection (UITextPosition position, UITextStorageDirection direction)
|
|
{
|
|
return UITextWritingDirection.LeftToRight;
|
|
}
|
|
|
|
// UITextInput protocol required method - Set the base writing direction for a
|
|
// given range of text in a document.
|
|
[Export ("setBaseWritingDirection:forRange:")]
|
|
void SetBaseWritingDirection (UITextWritingDirection writingDirection, UITextRange range)
|
|
{
|
|
// This sample assumes LTR text direction and does not currently support BiDi or RTL.
|
|
}
|
|
#endregion
|
|
#region UITextInput - Geometry methods
|
|
// UITextInput protocol required method - Return the first rectangle that encloses
|
|
// a range of text in a document.
|
|
[Export ("firstRectForRange:")]
|
|
CGRect FirstRect (UITextRange range)
|
|
{
|
|
// FIXME: the Objective-C code doesn't get a null range
|
|
// This is the reason why we don't get the autocorrection suggestions
|
|
// (it'll just autocorrect without showing any suggestions).
|
|
// Possibly due to http://bugzilla.xamarin.com/show_bug.cgi?id=265
|
|
IndexedRange r = (IndexedRange) (range ?? IndexedRange.GetRange (new NSRange (0, 1)));
|
|
// Use underlying SimpleCoreTextView to get rect for range
|
|
CGRect rect = textView.FirstRect (r.Range);
|
|
// Convert rect to our view coordinates
|
|
return ConvertRectFromView (rect, textView);
|
|
}
|
|
|
|
// UITextInput protocol required method - Return a rectangle used to draw the caret
|
|
// at a given insertion point.
|
|
[Export ("caretRectForPosition:")]
|
|
CGRect CaretRect (UITextPosition position)
|
|
{
|
|
// FIXME: the Objective-C code doesn't get a null position
|
|
// This is the reason why we don't get the autocorrection suggestions
|
|
// (it'll just autocorrect without showing any suggestions).
|
|
// Possibly due to http://bugzilla.xamarin.com/show_bug.cgi?id=265
|
|
IndexedPosition pos = (IndexedPosition) (position ?? IndexedPosition.GetPosition (0));
|
|
// Get caret rect from underlying SimpleCoreTextView
|
|
CGRect rect = textView.CaretRect (pos.Index);
|
|
// Convert rect to our view coordinates
|
|
return ConvertRectFromView (rect, textView);
|
|
}
|
|
#endregion
|
|
#region UITextInput - Hit testing
|
|
// Note that for this sample hit testing methods are not implemented, as there
|
|
// is no implemented mechanic for letting user select text via touches. There
|
|
// is a wide variety of approaches for this (gestures, drag rects, etc) and
|
|
// any approach chosen will depend greatly on the design of the application.
|
|
|
|
// UITextInput protocol required method - Return the position in a document that
|
|
// is closest to a specified point.
|
|
[Export ("closestPositionToPoint:")]
|
|
UITextPosition ClosestPosition (CGPoint point)
|
|
{
|
|
// Not implemented in this sample. Could utilize underlying
|
|
// SimpleCoreTextView:closestIndexToPoint:point
|
|
return null;
|
|
}
|
|
|
|
// UITextInput protocol required method - Return the position in a document that
|
|
// is closest to a specified point in a given range.
|
|
[Export ("closestPositionToPoint:withinRange:")]
|
|
UITextPosition ClosestPosition (CGPoint point, UITextRange range)
|
|
{
|
|
// Not implemented in this sample. Could utilize underlying
|
|
// SimpleCoreTextView:closestIndexToPoint:point
|
|
return null;
|
|
}
|
|
|
|
// UITextInput protocol required method - Return the character or range of
|
|
// characters that is at a given point in a document.
|
|
[Export ("characterRangeAtPoint:")]
|
|
UITextRange CharacterRange (CGPoint point)
|
|
{
|
|
// Not implemented in this sample. Could utilize underlying
|
|
// SimpleCoreTextView:closestIndexToPoint:point
|
|
return null;
|
|
}
|
|
#endregion
|
|
#region UITextInput - Returning Text Styling Information
|
|
// UITextInput protocol method - Return a dictionary with properties that specify
|
|
// how text is to be style at a certain location in a document.
|
|
[Export ("textStylingAtPosition:inDirection:")]
|
|
NSDictionary TextStyling (UITextPosition position, UITextStorageDirection direction)
|
|
{
|
|
// This sample assumes all text is single-styled, so this is easy.
|
|
return new NSDictionary (CTStringAttributeKey.Font, textView.Font);
|
|
}
|
|
#endregion
|
|
#region UIKeyInput methods
|
|
// UIKeyInput required method - A Boolean value that indicates whether the text-entry
|
|
// objects have any text.
|
|
[Export ("hasText")]
|
|
bool HasText {
|
|
get { return text.Length > 0; }
|
|
}
|
|
|
|
// UIKeyInput required method - Insert a character into the displayed text.
|
|
// Called by the text system when the user has entered simple text
|
|
[Export ("insertText:")]
|
|
void InsertText (string text)
|
|
{
|
|
NSRange selectedNSRange = textView.SelectedTextRange;
|
|
NSRange markedTextRange = textView.MarkedTextRange;
|
|
|
|
// Note: While this sample does not provide a way for the user to
|
|
// create marked or selected text, the following code still checks for
|
|
// these ranges and acts accordingly.
|
|
if (markedTextRange.Location != NSRange.NotFound) {
|
|
// There is marked text -- replace marked text with user-entered text
|
|
this.text.Remove ((int)markedTextRange.Location, (int)markedTextRange.Length);
|
|
this.text.Insert ((int)markedTextRange.Location, text);
|
|
selectedNSRange.Location = markedTextRange.Location + text.Length;
|
|
selectedNSRange.Length = 0;
|
|
markedTextRange = new NSRange (NSRange.NotFound, 0);
|
|
} else if (selectedNSRange.Length > 0) {
|
|
// Replace selected text with user-entered text
|
|
this.text.Remove ((int)selectedNSRange.Location, (int)selectedNSRange.Length);
|
|
this.text.Insert ((int)selectedNSRange.Location, text);
|
|
selectedNSRange.Length = 0;
|
|
selectedNSRange.Location += text.Length;
|
|
} else {
|
|
// Insert user-entered text at current insertion point
|
|
this.text.Insert ((int)selectedNSRange.Location, text);
|
|
selectedNSRange.Location += text.Length;
|
|
}
|
|
|
|
// Update underlying SimpleCoreTextView
|
|
textView.Text = this.text.ToString ();
|
|
textView.MarkedTextRange = markedTextRange;
|
|
textView.SelectedTextRange = selectedNSRange;
|
|
}
|
|
|
|
// UIKeyInput required method - Delete a character from the displayed text.
|
|
// Called by the text system when the user is invoking a delete (e.g. pressing
|
|
// the delete software keyboard key)
|
|
[Export ("deleteBackward")]
|
|
void DeleteBackward ()
|
|
{
|
|
NSRange selectedNSRange = textView.SelectedTextRange;
|
|
NSRange markedTextRange = textView.MarkedTextRange;
|
|
|
|
// Note: While this sample does not provide a way for the user to
|
|
// create marked or selected text, the following code still checks for
|
|
// these ranges and acts accordingly.
|
|
if (markedTextRange.Location != NSRange.NotFound) {
|
|
// There is marked text, so delete it
|
|
text.Remove ((int)markedTextRange.Location, (int)markedTextRange.Length);
|
|
selectedNSRange.Location = markedTextRange.Location;
|
|
selectedNSRange.Length = 0;
|
|
markedTextRange = new NSRange (NSRange.NotFound, 0);
|
|
} else if (selectedNSRange.Length > 0) {
|
|
// Delete the selected text
|
|
text.Remove ((int)selectedNSRange.Location, (int)selectedNSRange.Length);
|
|
selectedNSRange.Length = 0;
|
|
} else if (selectedNSRange.Location > 0) {
|
|
// Delete one char of text at the current insertion point
|
|
selectedNSRange.Location--;
|
|
selectedNSRange.Length = 1;
|
|
text.Remove ((int)selectedNSRange.Location, (int)selectedNSRange.Length);
|
|
selectedNSRange.Length = 0;
|
|
}
|
|
|
|
// Update underlying SimpleCoreTextView
|
|
textView.Text = text.ToString ();
|
|
textView.MarkedTextRange = markedTextRange;
|
|
textView.SelectedTextRange = selectedNSRange;
|
|
}
|
|
}
|
|
#endregion
|
|
#endregion
|
|
}
|