mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-18 23:48:29 +02:00
Merge MatrixKit develop with commit hash: b85b736313bec0592bd1cabc68035d97f5331137
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <Photos/Photos.h>
|
||||
|
||||
#import "MXKView.h"
|
||||
|
||||
/**
|
||||
List the predefined modes to handle the size of attached images
|
||||
*/
|
||||
typedef enum : NSUInteger
|
||||
{
|
||||
/**
|
||||
Prompt the user to select the compression level
|
||||
*/
|
||||
MXKRoomInputToolbarCompressionModePrompt,
|
||||
|
||||
/**
|
||||
The compression level is fixed for the following modes
|
||||
*/
|
||||
MXKRoomInputToolbarCompressionModeSmall,
|
||||
MXKRoomInputToolbarCompressionModeMedium,
|
||||
MXKRoomInputToolbarCompressionModeLarge,
|
||||
|
||||
/**
|
||||
No compression, the original image is sent
|
||||
*/
|
||||
MXKRoomInputToolbarCompressionModeNone
|
||||
|
||||
} MXKRoomInputToolbarCompressionMode;
|
||||
|
||||
|
||||
@class MXKRoomInputToolbarView;
|
||||
@protocol MXKRoomInputToolbarViewDelegate <NSObject>
|
||||
|
||||
/**
|
||||
Tells the delegate that an alert must be presented.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param alertController the alert to present.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView presentAlertController:(UIAlertController*)alertController;
|
||||
|
||||
/**
|
||||
Tells the delegate that the visibility of the status bar must be changed.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param isHidden tell whether the status bar must be hidden or not.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView hideStatusBar:(BOOL)isHidden;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Tells the delegate that the user is typing or has finished typing.
|
||||
|
||||
@param toolbarView the room input toolbar view
|
||||
@param typing YES if the user is typing inside the message composer.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView isTyping:(BOOL)typing;
|
||||
|
||||
/**
|
||||
Tells the delegate that toolbar height has been updated.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param height the updated height of toolbar view.
|
||||
@param completion a block object to be executed when height change is taken into account.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView heightDidChanged:(CGFloat)height completion:(void (^)(BOOL finished))completion;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to send a text message.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param textMessage the string to send.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView sendTextMessage:(NSString*)textMessage;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to send an image.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param image the UIImage hosting the image data to send.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView sendImage:(UIImage*)image;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to send an image.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param imageData the full-sized image data of the image.
|
||||
@param mimetype image mime type
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView sendImage:(NSData*)imageData withMimeType:(NSString*)mimetype;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to send a video.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param videoLocalURL the local filesystem path of the video to send.
|
||||
@param videoThumbnail the UIImage hosting a video thumbnail.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView sendVideo:(NSURL*)videoLocalURL withThumbnail:(UIImage*)videoThumbnail;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to send a video.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param videoAsset the AVAsset that represents the video to send.
|
||||
@param videoThumbnail the UIImage hosting a video thumbnail.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView sendVideoAsset:(AVAsset*)videoAsset withThumbnail:(UIImage*)videoThumbnail;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to send a file.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param fileLocalURL the local filesystem path of the file to send.
|
||||
@param mimetype file mime type
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView sendFile:(NSURL*)fileLocalURL withMimeType:(NSString*)mimetype;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants invite a matrix user.
|
||||
|
||||
Note: `Invite matrix user` option is displayed in actions list only if the delegate implements this method.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param mxUserId the Matrix user id.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView inviteMatrixUser:(NSString*)mxUserId;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to place a voice or a video call.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param video YES to make a video call.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView placeCallWithVideo:(BOOL)video;
|
||||
|
||||
/**
|
||||
Tells the delegate that the user wants to hangup the current call.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
*/
|
||||
- (void)roomInputToolbarViewHangupCall:(MXKRoomInputToolbarView*)toolbarView;
|
||||
|
||||
/**
|
||||
Tells the delegate to present a view controller modally.
|
||||
|
||||
Note: Media attachment is available only if the delegate implements this method.
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param viewControllerToPresent the view controller to present.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView presentViewController:(UIViewController*)viewControllerToPresent;
|
||||
|
||||
/**
|
||||
Tells the delegate to dismiss the view controller that was presented modally
|
||||
|
||||
@param toolbarView the room input toolbar view.
|
||||
@param flag Pass YES to animate the transition.
|
||||
@param completion The block to execute after the view controller is dismissed.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion;
|
||||
|
||||
/**
|
||||
Tells the delegate to start or stop an activity indicator.
|
||||
|
||||
@param toolbarView the room input toolbar view
|
||||
@param isAnimating YES if the activity indicator should run.
|
||||
*/
|
||||
- (void)roomInputToolbarView:(MXKRoomInputToolbarView*)toolbarView updateActivityIndicator:(BOOL)isAnimating;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
`MXKRoomInputToolbarView` instance is a view used to handle all kinds of available inputs
|
||||
for a room (message composer, attachments selection...).
|
||||
|
||||
By default the right button of the toolbar offers the following options: attach media, invite new members.
|
||||
By default the left button is used to send the content of the message composer.
|
||||
By default 'messageComposerContainer' is empty.
|
||||
*/
|
||||
@interface MXKRoomInputToolbarView : MXKView <UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
|
||||
/**
|
||||
The message composer container view. Your own message composer may be added inside this container.
|
||||
*/
|
||||
UIView *messageComposerContainer;
|
||||
|
||||
@protected
|
||||
UIView *inputAccessoryView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `UINib` object initialized for the tool bar view.
|
||||
*
|
||||
* @return The initialized `UINib` object or `nil` if there were errors during
|
||||
* initialization or the nib file could not be located.
|
||||
*/
|
||||
+ (UINib *)nib;
|
||||
|
||||
/**
|
||||
Creates and returns a new `MXKRoomInputToolbarView-inherited` object.
|
||||
|
||||
@discussion This is the designated initializer for programmatic instantiation.
|
||||
@return An initialized `MXKRoomInputToolbarView-inherited` object if successful, `nil` otherwise.
|
||||
*/
|
||||
+ (instancetype)roomInputToolbarView;
|
||||
|
||||
/**
|
||||
The delegate notified when inputs are ready.
|
||||
*/
|
||||
@property (weak, nonatomic) id<MXKRoomInputToolbarViewDelegate> delegate;
|
||||
|
||||
/**
|
||||
A custom button displayed on the left of the toolbar view.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet UIButton *leftInputToolbarButton;
|
||||
|
||||
/**
|
||||
A custom button displayed on the right of the toolbar view.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet UIButton *rightInputToolbarButton;
|
||||
|
||||
/**
|
||||
Layout constraint between the top of the message composer container and the top of its superview.
|
||||
The first view is the container, the second is the superview.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messageComposerContainerTopConstraint;
|
||||
|
||||
/**
|
||||
Layout constraint between the bottom of the message composer container and the bottom of its superview.
|
||||
The first view is the superview, the second is the container.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *messageComposerContainerBottomConstraint;
|
||||
|
||||
/**
|
||||
Tell whether the sent images and videos should be automatically saved in the user's photos library. NO by default.
|
||||
*/
|
||||
@property (nonatomic) BOOL enableAutoSaving;
|
||||
|
||||
/**
|
||||
Tell whether the text is editable. YES by default.
|
||||
*/
|
||||
@property(nonatomic, getter=isEditable) BOOL editable;
|
||||
|
||||
/**
|
||||
`onTouchUpInside` action is registered on `Touch Up Inside` event for both buttons (left and right input toolbar buttons).
|
||||
Override this method to customize user interaction handling
|
||||
|
||||
@param button the event sender
|
||||
*/
|
||||
- (IBAction)onTouchUpInside:(UIButton*)button;
|
||||
|
||||
/**
|
||||
Handle image attachment
|
||||
Save the image in user's photos library when 'isPhotoLibraryAsset' flag is NO and auto saving is enabled.
|
||||
|
||||
@param imageData the full-sized image data of the selected image.
|
||||
@param mimetype the image MIME type (nil if unknown).
|
||||
@param compressionMode the compression mode to apply on this image. This option is considered only for jpeg image.
|
||||
@param isPhotoLibraryAsset tell whether the image has been selected from the user's photos library or not.
|
||||
*/
|
||||
- (void)sendSelectedImage:(NSData*)imageData withMimeType:(NSString *)mimetype andCompressionMode:(MXKRoomInputToolbarCompressionMode)compressionMode isPhotoLibraryAsset:(BOOL)isPhotoLibraryAsset;
|
||||
|
||||
/**
|
||||
Handle video attachment.
|
||||
Save the video in user's photos library when 'isPhotoLibraryAsset' flag is NO and auto saving is enabled.
|
||||
|
||||
@param selectedVideo the local url of the video to send.
|
||||
@param isPhotoLibraryAsset tell whether the video has been selected from user's photos library.
|
||||
*/
|
||||
- (void)sendSelectedVideo:(NSURL*)selectedVideo isPhotoLibraryAsset:(BOOL)isPhotoLibraryAsset;
|
||||
|
||||
/**
|
||||
Handle video attachment.
|
||||
Save the video in user's photos library when 'isPhotoLibraryAsset' flag is NO and auto saving is enabled.
|
||||
|
||||
@param selectedVideo an AVAsset that represents the video to send.
|
||||
@param isPhotoLibraryAsset tell whether the video has been selected from user's photos library.
|
||||
*/
|
||||
- (void)sendSelectedVideoAsset:(AVAsset*)selectedVideo isPhotoLibraryAsset:(BOOL)isPhotoLibraryAsset;
|
||||
|
||||
/**
|
||||
Handle multiple media attachments according to the compression mode.
|
||||
|
||||
@param assets the selected assets.
|
||||
@param compressionMode the compression mode to apply on the media. This option is considered only for jpeg image.
|
||||
*/
|
||||
- (void)sendSelectedAssets:(NSArray<PHAsset*>*)assets withCompressionMode:(MXKRoomInputToolbarCompressionMode)compressionMode;
|
||||
|
||||
/**
|
||||
The maximum height of the toolbar.
|
||||
A value <= 0 means no limit.
|
||||
*/
|
||||
@property CGFloat maxHeight;
|
||||
|
||||
/**
|
||||
The current text message in message composer.
|
||||
*/
|
||||
@property NSString *textMessage;
|
||||
|
||||
/**
|
||||
The string that should be displayed when there is no other text in message composer.
|
||||
This property may be ignored when message composer does not support placeholder display.
|
||||
*/
|
||||
@property (nonatomic) NSString *placeholder;
|
||||
|
||||
/**
|
||||
The custom accessory view associated with the message composer. This view is
|
||||
actually used to retrieve the keyboard view. Indeed the keyboard view is the superview of
|
||||
the accessory view when the message composer become the first responder.
|
||||
*/
|
||||
@property (readonly) UIView *inputAccessoryView;
|
||||
|
||||
/**
|
||||
Display the keyboard.
|
||||
*/
|
||||
- (BOOL)becomeFirstResponder;
|
||||
|
||||
/**
|
||||
Force dismiss keyboard.
|
||||
*/
|
||||
- (void)dismissKeyboard;
|
||||
|
||||
/**
|
||||
Dispose any resources and listener.
|
||||
*/
|
||||
- (void)destroy;
|
||||
|
||||
/**
|
||||
Paste a text in textMessage.
|
||||
|
||||
The text is pasted at the current cursor location in the message composer or it
|
||||
replaces the currently selected text.
|
||||
|
||||
@param text the text to paste.
|
||||
*/
|
||||
- (void)pasteText:(NSString*)text;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MXKRoomInputToolbarView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="41"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="contactAdd" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hga-l8-Wua" userLabel="left Button">
|
||||
<rect key="frame" x="8" y="0.0" width="35" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="35" id="ptO-BQ-NhS"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="WbU-WH-gwL"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Owf-M8-qJi" userLabel="right Button">
|
||||
<rect key="frame" x="552" y="0.0" width="44" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="9FZ-CI-diT"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Send">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="Cxg-BO-TfK"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QWp-NV-uh5" userLabel="Message Composer Container">
|
||||
<rect key="frame" x="51" y="4" width="497" height="33"/>
|
||||
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="Owf-M8-qJi" secondAttribute="trailing" constant="4" id="2M8-Gu-0f6"/>
|
||||
<constraint firstItem="QWp-NV-uh5" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="4" id="570-8j-VYY"/>
|
||||
<constraint firstAttribute="bottom" secondItem="QWp-NV-uh5" secondAttribute="bottom" constant="4" id="9Ya-0H-03W"/>
|
||||
<constraint firstItem="Hga-l8-Wua" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="Bc8-T7-wmA"/>
|
||||
<constraint firstItem="Hga-l8-Wua" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Cvk-xZ-ODy"/>
|
||||
<constraint firstItem="Owf-M8-qJi" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="SV8-U3-8dd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Hga-l8-Wua" secondAttribute="bottom" id="Slr-2H-laO"/>
|
||||
<constraint firstItem="Owf-M8-qJi" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="trailing" constant="4" id="UEd-gb-jgR"/>
|
||||
<constraint firstItem="QWp-NV-uh5" firstAttribute="leading" secondItem="Hga-l8-Wua" secondAttribute="trailing" constant="8" id="cCr-Am-M7d"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Owf-M8-qJi" secondAttribute="bottom" id="ycc-x9-PAv"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="leftInputToolbarButton" destination="Hga-l8-Wua" id="jaa-D6-e6X"/>
|
||||
<outlet property="messageComposerContainer" destination="QWp-NV-uh5" id="APR-B5-ogC"/>
|
||||
<outlet property="messageComposerContainerBottomConstraint" destination="9Ya-0H-03W" id="dFh-N3-eDb"/>
|
||||
<outlet property="messageComposerContainerTopConstraint" destination="570-8j-VYY" id="dbB-W8-bro"/>
|
||||
<outlet property="rightInputToolbarButton" destination="Owf-M8-qJi" id="UQH-fw-chf"/>
|
||||
</connections>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomInputToolbarView.h"
|
||||
|
||||
#import <HPGrowingTextView/HPGrowingTextView.h>
|
||||
|
||||
/**
|
||||
`MXKRoomInputToolbarViewWithHPGrowingText` is a MXKRoomInputToolbarView-inherited class in which message
|
||||
composer is based on `HPGrowingTextView`.
|
||||
|
||||
Toolbar buttons are not overridden by this class. We keep the default implementation.
|
||||
*/
|
||||
@interface MXKRoomInputToolbarViewWithHPGrowingText : MXKRoomInputToolbarView <HPGrowingTextViewDelegate>
|
||||
{
|
||||
@protected
|
||||
HPGrowingTextView *growingTextView;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomInputToolbarViewWithHPGrowingText.h"
|
||||
|
||||
@interface MXKRoomInputToolbarViewWithHPGrowingText()
|
||||
{
|
||||
// HPGrowingTextView triggers growingTextViewDidChange event when it recomposes itself
|
||||
// Save the last edited text to prevent unexpected typing events
|
||||
NSString* lastEditedText;
|
||||
}
|
||||
|
||||
/**
|
||||
Message composer defined in `messageComposerContainer`.
|
||||
*/
|
||||
@property (nonatomic) IBOutlet HPGrowingTextView *growingTextView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKRoomInputToolbarViewWithHPGrowingText
|
||||
@synthesize growingTextView;
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass([MXKRoomInputToolbarViewWithHPGrowingText class])
|
||||
bundle:[NSBundle bundleForClass:[MXKRoomInputToolbarViewWithHPGrowingText class]]];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
|
||||
// Handle message composer based on HPGrowingTextView use
|
||||
growingTextView.delegate = self;
|
||||
|
||||
[growingTextView setTranslatesAutoresizingMaskIntoConstraints: NO];
|
||||
|
||||
// Add an accessory view to the text view in order to retrieve keyboard view.
|
||||
inputAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
growingTextView.internalTextView.inputAccessoryView = self.inputAccessoryView;
|
||||
|
||||
// on IOS 8, the growing textview animation could trigger weird UI animations
|
||||
// indeed, the messages tableView can be refreshed while its height is updated (e.g. when setting a message)
|
||||
growingTextView.animateHeightChange = NO;
|
||||
|
||||
lastEditedText = nil;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self destroy];
|
||||
}
|
||||
|
||||
-(void)customizeViewRendering
|
||||
{
|
||||
[super customizeViewRendering];
|
||||
|
||||
// set text input font
|
||||
growingTextView.font = [UIFont systemFontOfSize:14];
|
||||
|
||||
// draw a rounded border around the textView
|
||||
growingTextView.layer.cornerRadius = 5;
|
||||
growingTextView.layer.borderWidth = 1;
|
||||
growingTextView.layer.borderColor = [UIColor lightGrayColor].CGColor;
|
||||
growingTextView.clipsToBounds = YES;
|
||||
growingTextView.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
if (growingTextView)
|
||||
{
|
||||
growingTextView.delegate = nil;
|
||||
growingTextView = nil;
|
||||
}
|
||||
|
||||
[super destroy];
|
||||
}
|
||||
|
||||
- (void)setMaxHeight:(CGFloat)maxHeight
|
||||
{
|
||||
growingTextView.maxHeight = maxHeight - (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant);
|
||||
[growingTextView refreshHeight];
|
||||
|
||||
super.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
- (NSString*)textMessage
|
||||
{
|
||||
return growingTextView.text;
|
||||
}
|
||||
|
||||
- (void)setTextMessage:(NSString *)textMessage
|
||||
{
|
||||
growingTextView.text = textMessage;
|
||||
self.rightInputToolbarButton.enabled = textMessage.length;
|
||||
}
|
||||
|
||||
- (void)pasteText:(NSString *)text
|
||||
{
|
||||
self.textMessage = [growingTextView.text stringByReplacingCharactersInRange:growingTextView.selectedRange withString:text];
|
||||
}
|
||||
|
||||
- (void)setPlaceholder:(NSString *)inPlaceholder
|
||||
{
|
||||
[super setPlaceholder:inPlaceholder];
|
||||
growingTextView.placeholder = inPlaceholder;
|
||||
}
|
||||
|
||||
- (BOOL)becomeFirstResponder
|
||||
{
|
||||
return [growingTextView becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (void)dismissKeyboard
|
||||
{
|
||||
[growingTextView resignFirstResponder];
|
||||
}
|
||||
|
||||
#pragma mark - HPGrowingTextView delegate
|
||||
|
||||
- (void)growingTextViewDidEndEditing:(HPGrowingTextView *)sender
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self isTyping:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)growingTextViewDidChange:(HPGrowingTextView *)sender
|
||||
{
|
||||
NSString *msg = growingTextView.text;
|
||||
|
||||
// HPGrowingTextView triggers growingTextViewDidChange event when it recomposes itself.
|
||||
// Save the last edited text to prevent unexpected typing events
|
||||
if (![lastEditedText isEqualToString:msg])
|
||||
{
|
||||
lastEditedText = msg;
|
||||
if (msg.length)
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self isTyping:YES];
|
||||
}
|
||||
self.rightInputToolbarButton.enabled = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self isTyping:NO];
|
||||
}
|
||||
self.rightInputToolbarButton.enabled = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)growingTextView:(HPGrowingTextView *)growingTextView willChangeHeight:(float)height
|
||||
{
|
||||
// Update growing text's superview (toolbar view)
|
||||
CGFloat updatedHeight = height + (self.messageComposerContainerTopConstraint.constant + self.messageComposerContainerBottomConstraint.constant);
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:heightDidChanged:completion:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self heightDidChanged:updatedHeight completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)growingTextView:(HPGrowingTextView *)growingTextView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
|
||||
{
|
||||
return self.isEditable;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MXKRoomInputToolbarViewWithHPGrowingText">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="41"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="contactAdd" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hga-l8-Wua" userLabel="left Button">
|
||||
<rect key="frame" x="8" y="0.0" width="35" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="35" id="ptO-BQ-NhS"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="jVG-We-DmS"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Owf-M8-qJi" userLabel="right Button">
|
||||
<rect key="frame" x="552" y="0.0" width="44" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="44" id="9FZ-CI-diT"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Send">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="jed-Mz-rxe"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QWp-NV-uh5" userLabel="Message Composer Container">
|
||||
<rect key="frame" x="51" y="4" width="497" height="33"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pkf-YH-tco" customClass="HPGrowingTextView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="497" height="33"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="pkf-YH-tco" secondAttribute="bottom" id="L3A-Oo-Ml2"/>
|
||||
<constraint firstItem="pkf-YH-tco" firstAttribute="top" secondItem="QWp-NV-uh5" secondAttribute="top" id="VPn-k0-0vc"/>
|
||||
<constraint firstItem="pkf-YH-tco" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="leading" id="mXj-f3-DcT"/>
|
||||
<constraint firstAttribute="trailing" secondItem="pkf-YH-tco" secondAttribute="trailing" id="n4K-Do-gHr"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.89720267057418823" green="0.89720267057418823" blue="0.89720267057418823" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="Owf-M8-qJi" secondAttribute="trailing" constant="4" id="2M8-Gu-0f6"/>
|
||||
<constraint firstItem="QWp-NV-uh5" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="4" id="570-8j-VYY"/>
|
||||
<constraint firstAttribute="bottom" secondItem="QWp-NV-uh5" secondAttribute="bottom" constant="4" id="9Ya-0H-03W"/>
|
||||
<constraint firstItem="Hga-l8-Wua" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="Bc8-T7-wmA"/>
|
||||
<constraint firstItem="Hga-l8-Wua" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Cvk-xZ-ODy"/>
|
||||
<constraint firstItem="Owf-M8-qJi" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="SV8-U3-8dd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Hga-l8-Wua" secondAttribute="bottom" id="Slr-2H-laO"/>
|
||||
<constraint firstItem="Owf-M8-qJi" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="trailing" constant="4" id="UEd-gb-jgR"/>
|
||||
<constraint firstItem="QWp-NV-uh5" firstAttribute="leading" secondItem="Hga-l8-Wua" secondAttribute="trailing" constant="8" id="cCr-Am-M7d"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Owf-M8-qJi" secondAttribute="bottom" id="ycc-x9-PAv"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="growingTextView" destination="pkf-YH-tco" id="VeP-WI-6Xh"/>
|
||||
<outlet property="leftInputToolbarButton" destination="Hga-l8-Wua" id="zbm-3b-hoY"/>
|
||||
<outlet property="messageComposerContainer" destination="QWp-NV-uh5" id="7EX-Un-ZIe"/>
|
||||
<outlet property="messageComposerContainerBottomConstraint" destination="9Ya-0H-03W" id="226-iu-6tU"/>
|
||||
<outlet property="messageComposerContainerTopConstraint" destination="570-8j-VYY" id="VKv-Qh-PCs"/>
|
||||
<outlet property="rightInputToolbarButton" destination="Owf-M8-qJi" id="seO-ly-Bgg"/>
|
||||
</connections>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomInputToolbarView.h"
|
||||
|
||||
/**
|
||||
`MXKRoomInputToolbarViewWithSimpleTextView` is a MXKRoomInputToolbarView-inherited class in which message
|
||||
composer is a UITextView instance with a fixed heigth.
|
||||
|
||||
Toolbar buttons are not overridden by this class. We keep the default implementation.
|
||||
*/
|
||||
@interface MXKRoomInputToolbarViewWithSimpleTextView : MXKRoomInputToolbarView <UITextViewDelegate>
|
||||
|
||||
/**
|
||||
Message composer defined in `messageComposerContainer`.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet UITextView *messageComposerTextView;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomInputToolbarViewWithSimpleTextView.h"
|
||||
|
||||
@implementation MXKRoomInputToolbarViewWithSimpleTextView
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass([MXKRoomInputToolbarViewWithSimpleTextView class])
|
||||
bundle:[NSBundle bundleForClass:[MXKRoomInputToolbarViewWithSimpleTextView class]]];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
|
||||
// Add an accessory view to the text view in order to retrieve keyboard view.
|
||||
inputAccessoryView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
self.messageComposerTextView.inputAccessoryView = self.inputAccessoryView;
|
||||
}
|
||||
|
||||
-(void)customizeViewRendering
|
||||
{
|
||||
[super customizeViewRendering];
|
||||
|
||||
// Set default message composer background color
|
||||
self.messageComposerTextView.backgroundColor = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
- (NSString*)textMessage
|
||||
{
|
||||
return _messageComposerTextView.text;
|
||||
}
|
||||
|
||||
- (void)setTextMessage:(NSString *)textMessage
|
||||
{
|
||||
_messageComposerTextView.text = textMessage;
|
||||
self.rightInputToolbarButton.enabled = textMessage.length;
|
||||
}
|
||||
|
||||
- (void)pasteText:(NSString *)text
|
||||
{
|
||||
self.textMessage = [_messageComposerTextView.text stringByReplacingCharactersInRange:_messageComposerTextView.selectedRange withString:text];
|
||||
}
|
||||
|
||||
- (BOOL)becomeFirstResponder
|
||||
{
|
||||
return [_messageComposerTextView becomeFirstResponder];
|
||||
}
|
||||
|
||||
- (void)dismissKeyboard
|
||||
{
|
||||
if (_messageComposerTextView)
|
||||
{
|
||||
[_messageComposerTextView resignFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITextViewDelegate
|
||||
|
||||
- (void)textViewDidEndEditing:(UITextView *)textView
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self isTyping:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)textViewDidChange:(UITextView *)textView
|
||||
{
|
||||
NSString *msg = textView.text;
|
||||
|
||||
if (msg.length)
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self isTyping:YES];
|
||||
}
|
||||
self.rightInputToolbarButton.enabled = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(roomInputToolbarView:isTyping:)])
|
||||
{
|
||||
[self.delegate roomInputToolbarView:self isTyping:NO];
|
||||
}
|
||||
self.rightInputToolbarButton.enabled = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
|
||||
{
|
||||
if (!self.isEditable)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
// Hanlde here `Done` key pressed
|
||||
if([text isEqualToString:@"\n"])
|
||||
{
|
||||
[textView resignFirstResponder];
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MXKRoomInputToolbarViewWithSimpleTextView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="41"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="contactAdd" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Hga-l8-Wua" userLabel="left Button">
|
||||
<rect key="frame" x="8" y="0.0" width="35" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="35" id="ptO-BQ-NhS"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="mKx-fF-gCc"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Owf-M8-qJi" userLabel="right Button">
|
||||
<rect key="frame" x="556" y="0.0" width="36" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="35" id="9FZ-CI-diT"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Send">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="onTouchUpInside:" destination="iN0-l3-epB" eventType="touchUpInside" id="NBz-Y3-Fnd"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QWp-NV-uh5" userLabel="Message Composer Container">
|
||||
<rect key="frame" x="51" y="4" width="497" height="33"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="24Y-ae-xvw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="497" height="33"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences" returnKeyType="done"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="iN0-l3-epB" id="b2v-6r-Ket"/>
|
||||
</connections>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="24Y-ae-xvw" secondAttribute="bottom" id="Orh-Lx-4pU"/>
|
||||
<constraint firstItem="24Y-ae-xvw" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="leading" id="e9C-Ki-9vO"/>
|
||||
<constraint firstAttribute="trailing" secondItem="24Y-ae-xvw" secondAttribute="trailing" id="flk-jG-qWQ"/>
|
||||
<constraint firstItem="24Y-ae-xvw" firstAttribute="top" secondItem="QWp-NV-uh5" secondAttribute="top" id="urH-zt-PuK"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="Owf-M8-qJi" secondAttribute="trailing" constant="8" id="2M8-Gu-0f6"/>
|
||||
<constraint firstItem="QWp-NV-uh5" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="4" id="570-8j-VYY"/>
|
||||
<constraint firstAttribute="bottom" secondItem="QWp-NV-uh5" secondAttribute="bottom" constant="4" id="9Ya-0H-03W"/>
|
||||
<constraint firstItem="Hga-l8-Wua" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="Bc8-T7-wmA"/>
|
||||
<constraint firstItem="Hga-l8-Wua" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Cvk-xZ-ODy"/>
|
||||
<constraint firstItem="Owf-M8-qJi" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="SV8-U3-8dd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Hga-l8-Wua" secondAttribute="bottom" id="Slr-2H-laO"/>
|
||||
<constraint firstItem="Owf-M8-qJi" firstAttribute="leading" secondItem="QWp-NV-uh5" secondAttribute="trailing" constant="8" id="UEd-gb-jgR"/>
|
||||
<constraint firstItem="QWp-NV-uh5" firstAttribute="leading" secondItem="Hga-l8-Wua" secondAttribute="trailing" constant="8" id="cCr-Am-M7d"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Owf-M8-qJi" secondAttribute="bottom" id="ycc-x9-PAv"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="leftInputToolbarButton" destination="Hga-l8-Wua" id="KSc-TM-g5i"/>
|
||||
<outlet property="messageComposerContainer" destination="QWp-NV-uh5" id="7BM-Ni-5BB"/>
|
||||
<outlet property="messageComposerContainerBottomConstraint" destination="9Ya-0H-03W" id="67R-BO-8aU"/>
|
||||
<outlet property="messageComposerContainerTopConstraint" destination="570-8j-VYY" id="vbj-Ud-SLi"/>
|
||||
<outlet property="messageComposerTextView" destination="24Y-ae-xvw" id="Sbt-Gf-WvF"/>
|
||||
<outlet property="rightInputToolbarButton" destination="Owf-M8-qJi" id="nvK-y3-iE5"/>
|
||||
</connections>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
Reference in New Issue
Block a user