|
|
|
@ -3,6 +3,7 @@
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#import "OWSMessageTextView.h"
|
|
|
|
|
#import <SignalMessaging/UIView+OWS.h>
|
|
|
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
|
|
|
|
@ -60,6 +61,47 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Add unit test.
|
|
|
|
|
- (CGSize)compactSizeThatFitsMaxWidth:(CGFloat)maxWidth maxIterations:(NSUInteger)maxIterations
|
|
|
|
|
{
|
|
|
|
|
OWSAssert(maxWidth > 0);
|
|
|
|
|
|
|
|
|
|
CGSize textSize = CGSizeCeil([self sizeThatFits:CGSizeMake(maxWidth, CGFLOAT_MAX)]);
|
|
|
|
|
|
|
|
|
|
// "Compact" layout to reduce "widows",
|
|
|
|
|
// e.g. last lines with only a single word.
|
|
|
|
|
//
|
|
|
|
|
// After measuring the size of the text, we try to find smaller widths
|
|
|
|
|
// in which the text will fit without adding any height, by wrapping
|
|
|
|
|
// more text onto the last line. We use a binary search.
|
|
|
|
|
if (textSize.width > 0 && textSize.height > 0) {
|
|
|
|
|
NSUInteger upperBound = (NSUInteger)textSize.width;
|
|
|
|
|
NSUInteger lowerBound = 1;
|
|
|
|
|
// The more iterations we perform in our binary search,
|
|
|
|
|
// the more accurate the result, but the more expensive
|
|
|
|
|
// layout becomes.
|
|
|
|
|
for (NSUInteger i = 0; i < maxIterations; i++) {
|
|
|
|
|
NSUInteger resizeWidth = (upperBound + lowerBound) / 2;
|
|
|
|
|
if (resizeWidth >= upperBound || resizeWidth <= lowerBound) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
CGSize resizeSize = CGSizeCeil([self sizeThatFits:CGSizeMake(resizeWidth, CGFLOAT_MAX)]);
|
|
|
|
|
BOOL success
|
|
|
|
|
= (resizeSize.width > 0 && resizeSize.width <= resizeWidth && resizeSize.height <= textSize.height);
|
|
|
|
|
if (success) {
|
|
|
|
|
// Success.
|
|
|
|
|
textSize = resizeSize;
|
|
|
|
|
upperBound = (NSUInteger)textSize.width;
|
|
|
|
|
} else {
|
|
|
|
|
// Failure.
|
|
|
|
|
lowerBound = resizeWidth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
textSize.width = MIN(textSize.width, maxWidth);
|
|
|
|
|
return CGSizeCeil(textSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
|