├── 1.html ├── README.mdown ├── RKRichTextView ├── RKRichTextView.h ├── RKRichTextView.html ├── RKRichTextView.m ├── RKRichTextViewListener.h ├── RKRichTextViewListener.m └── RKRichTextViewToolbar.xib ├── RichTextViewDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── RichTextViewDemo.xccheckout │ └── xcuserdata │ │ ├── admin.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings │ │ └── renat.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── admin.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints.xcbkptlist │ └── xcschemes │ │ ├── RichTextViewDemo.xcscheme │ │ └── xcschememanagement.plist │ └── renat.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── RichTextViewDemo.xcscheme │ └── xcschememanagement.plist ├── RichTextViewDemo ├── AppDelegate.h ├── AppDelegate.m ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── RichTextViewDemo-Info.plist ├── RichTextViewDemo-Prefix.pch ├── ViewController.h ├── ViewController.m ├── en.lproj │ ├── InfoPlist.strings │ ├── ViewController_iPad.xib │ └── ViewController_iPhone.xib └── main.m ├── config_version.txt ├── config_version2.txt ├── config_version3.txt └── screen.png /1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 35 | 36 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | # About RKRichTextView 2 | RKRichTextView is one of the most advanced Editable Rich Text Views. 3 | Works well on iOS 6/7 for iPhone/iPad. 4 | ![Screenshot](https://github.com/ren6/RKRichTextView/raw/master/screen.png) 5 | # How to use 6 | 7 | ``` objective-c 8 | 9 | // in header 10 | #import "RKRichTextView.h" 11 | 12 | // in code 13 | RKRichTextView *richTextView = [[[RKRichTextView alloc] initWithFrame:CGRectMake(20, 100, self.view.frame.size.width-40, 200)] autorelease]; 14 | [self.view addSubview:richTextView]; 15 | richTextView.aDelegate = self; 16 | ``` 17 | 18 | # Documentation 19 | Check out each header file for a complete listing of each method. 20 | 21 | # Questions 22 | Feel free to contact renat.kurbanov@gmail.com if you need any help with RKRichTextView. 23 | 24 | # License 25 | Copyright (c) 2013 Renat Kurbanov 26 | 27 | Permission is hereby granted, free of charge, to any person obtaining a copy 28 | of this software and associated documentation files (the "Software"), to deal 29 | in the Software without restriction, including without limitation the rights 30 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 31 | copies of the Software, and to permit persons to whom the Software is 32 | furnished to do so, subject to the following conditions: 33 | 34 | The above copyright notice and this permission notice shall be included in 35 | all copies or substantial portions of the Software. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 43 | THE SOFTWARE. 44 | -------------------------------------------------------------------------------- /RKRichTextView/RKRichTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RKRichTextView.h 3 | // 4 | // Created by ren6 on 2/1/13. 5 | // 6 | 7 | #import 8 | #import "RKRichTextViewListener.h" 9 | 10 | /** 11 | Add observers for following notifications if needed 12 | **/ 13 | extern NSString * const WRKRichTextViewWillBecomeFirstResponder; 14 | extern NSString * const WRKRichTextViewWillResignFirstResponder; 15 | 16 | 17 | @class RKRichTextView; 18 | @protocol RKRichTextViewDelegate 19 | @optional 20 | -(void) prevNextControlTouched:(UISegmentedControl*)control; 21 | -(void) richTextViewDidChange:(RKRichTextView *)richTextView; 22 | -(void) richTextViewDidLoad:(RKRichTextView*)richTextView; 23 | -(void) richTextViewWillReceiveFocus:(RKRichTextView*)richTextView; 24 | -(void) richTextViewWillLooseFocus:(RKRichTextView*)richTextView; 25 | @end 26 | 27 | @interface RKRichTextView : UIWebView 28 | 29 | @property (nonatomic, assign) BOOL isTheOnlyRichTextView; // Recommended to use. If set to YES, then rich text view will not create a temporary text field and then will not make first responder and resign. See ResignFirstResponder method. Default is NO. 30 | 31 | @property (nonatomic, assign) BOOL isActiveResponder; // don't want to override isFirstResponder property 32 | @property (nonatomic, assign) id aDelegate; 33 | @property (nonatomic, retain) UIView *toolbarView; 34 | @property (nonatomic, retain) UIToolbar *toolbar; 35 | @property (nonatomic, retain) UIToolbar *toolbariPhone; 36 | @property (nonatomic, assign) UIView *modalView; 37 | @property (nonatomic, retain) NSString *text; // HTML Text 38 | -(int) contentSizeHeight; 39 | -(BOOL) becomeFirstResponder; 40 | -(BOOL)resignFirstResponder; 41 | -(void) setMinimumHeight:(int)newHeight; 42 | @end 43 | -------------------------------------------------------------------------------- /RKRichTextView/RKRichTextView.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 76 | 120 | 121 |
122 |
{%content}
123 |
124 | 125 | -------------------------------------------------------------------------------- /RKRichTextView/RKRichTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RKRichTextView.m 3 | // 4 | // Created by ren6 on 2/1/13. 5 | // 6 | #import 7 | #import "RKRichTextView.h" 8 | #import "objc/runtime.h" 9 | #define RK_IS_IPAD ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) 10 | #define RK_IS_IPHONE ([UIDevice currentDevice].userInterfaceIdiom != UIUserInterfaceIdiomPad) 11 | 12 | #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 13 | 14 | 15 | NSString * const WRKRichTextViewWillBecomeFirstResponder = @"richTextViewWillBecomeFirstResponder"; 16 | NSString * const WRKRichTextViewWillResignFirstResponder = @"richTextViewWillResignFirstResponder"; 17 | 18 | @interface _SwizzleAccessoryViewRemover : NSObject 19 | 20 | @end 21 | 22 | @implementation _SwizzleAccessoryViewRemover 23 | 24 | -(id)inputAccessoryView 25 | { 26 | return nil; 27 | } 28 | 29 | @end 30 | 31 | @interface RKRichTextView() 32 | -(void) willChangeHeight:(int)newHeight; 33 | -(void) willDidLoad; 34 | -(void) onFocus; 35 | -(void) onFocusOut; 36 | -(void) touchMoved; 37 | -(void) touchEnded; 38 | @end 39 | @implementation RKRichTextView{ 40 | CGRect keyboardFrame; 41 | RKRichTextViewListener *listener; 42 | CGAffineTransform rotate; 43 | BOOL isHiding; BOOL isShowing; 44 | float screenHeight; 45 | int minHeight; 46 | BOOL _isAlreadySwizzle; 47 | 48 | UIColor *_selectedColor; 49 | UIColor *_deselectedColor; 50 | } 51 | @synthesize isActiveResponder; 52 | -(void) dealloc{ 53 | [listener release]; 54 | [self.toolbarView removeFromSuperview]; 55 | self.toolbarView = nil; 56 | self.toolbar = nil; 57 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 58 | [super dealloc]; 59 | } 60 | -(void) richTextViewTapped{ 61 | [self becomeFirstResponder]; 62 | } 63 | -(void) awakeFromNib{ 64 | [super awakeFromNib]; 65 | [self swizzleMethod]; 66 | [self setup]; 67 | } 68 | -(id)init{ 69 | self = [super init]; 70 | if (self){ 71 | [self swizzleMethod]; 72 | [self setup]; 73 | } 74 | return self; 75 | } 76 | -(id)initWithFrame:(CGRect)frame{ 77 | self = [super initWithFrame:frame]; 78 | if (self){ 79 | [self swizzleMethod]; 80 | [self setup]; 81 | } 82 | return self; 83 | } 84 | 85 | -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{ 86 | return nil; // if disable zooming then content offset will remain still 87 | } 88 | 89 | -(void)setupVersionsDifference 90 | { 91 | if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { 92 | [self.toolbar setBackgroundColor:[UIColor colorWithWhite:240.0f/255.0f alpha:1]]; 93 | [self.toolbar setBarStyle:UIBarStyleDefault]; 94 | [self.toolbar setTranslucent:NO]; 95 | 96 | _selectedColor = [UIColor colorWithRed:0 green:0.478431 blue:1 alpha:1]; 97 | _deselectedColor = [UIColor colorWithRed:95.0f/255.0f green:97.0f/255.0f blue:106.0f/255.0f alpha:1.0f]; 98 | 99 | 100 | for (UIBarButtonItem *item in self.toolbar.items){ 101 | if (item.tag==10){ 102 | // for DONE 103 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName:_selectedColor} forState:UIControlStateNormal]; 104 | } else if (item.tag==100){ 105 | UISegmentedControl *segmentControl = ((UISegmentedControl*)[item customView]); 106 | [segmentControl setTitleTextAttributes:@{NSForegroundColorAttributeName:_selectedColor} forState:UIControlStateNormal]; 107 | UIImage *image = [UIImage new]; 108 | [segmentControl setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 109 | [segmentControl setBackgroundImage:image forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 110 | [segmentControl setDividerImage:image forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 111 | [segmentControl setDividerImage:image forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 112 | [segmentControl setDividerImage:image forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 113 | } 114 | } 115 | 116 | } else { 117 | } 118 | } 119 | -(void) setup{ 120 | self.scalesPageToFit = YES; 121 | self.scrollView.bounces = NO; 122 | self.opaque = NO; 123 | self.backgroundColor = [UIColor whiteColor]; 124 | self.scrollView.delegate = self; 125 | listener = [[RKRichTextViewListener alloc] init]; 126 | listener.richTextView = self; 127 | 128 | screenHeight = [[UIScreen mainScreen] bounds].size.height; 129 | 130 | self.delegate = listener; 131 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 132 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 133 | int index = (RK_IS_IPAD? 0:1); 134 | self.toolbarView = [[[NSBundle mainBundle] loadNibNamed:@"RKRichTextViewToolbar" owner:nil options:nil] objectAtIndex:index]; 135 | CGRect aFrame = self.toolbarView.frame; 136 | aFrame.origin = CGPointMake(0, screenHeight); 137 | 138 | self.toolbarView.frame = aFrame; 139 | self.toolbarView.hidden = YES; 140 | [[UIApplication sharedApplication].delegate.window addSubview:self.toolbarView]; 141 | 142 | self.toolbar = (UIToolbar*)[self.toolbarView viewWithTag:10]; 143 | [self setupVersionsDifference]; 144 | for (UIBarButtonItem *item in self.toolbar.items){ 145 | if (item.tag==1){ 146 | [item setAction:@selector(boldAction:)]; 147 | [item setTarget:self]; 148 | } else if (item.tag==2){ 149 | [item setAction:@selector(italicAction:)]; 150 | [item setTarget:self]; 151 | } else if (item.tag==3){ 152 | [item setAction:@selector(underlineAction:)]; 153 | [item setTarget:self]; 154 | } else if (item.tag==4){ 155 | [item setAction:@selector(strikeAction:)]; 156 | [item setTarget:self]; 157 | } else if (item.tag==5){ 158 | [item setAction:@selector(orderedAction:)]; 159 | [item setTarget:self]; 160 | } else if (item.tag==6){ 161 | [item setAction:@selector(unorderedAction:)]; 162 | [item setTarget:self]; 163 | } else if (item.tag==7){ 164 | [item setAction:@selector(colorAction:)]; 165 | [item setTarget:self]; 166 | } else if (item.tag==10){ 167 | [item setAction:@selector(resignFirstResponder)]; 168 | [item setTarget:self]; 169 | } else if (item.tag==100){ 170 | [((UISegmentedControl*)[item customView]) addTarget:self action:@selector(didChangeSegmentControl:) forControlEvents:UIControlEventValueChanged]; 171 | } 172 | } 173 | [self checkSelections]; 174 | 175 | if (minHeight==0){ 176 | 177 | if (RK_IS_IPAD) 178 | minHeight = 73; 179 | else 180 | minHeight = ((int)self.frame.size.height - 12); 181 | } 182 | [self setText:@""]; 183 | } 184 | 185 | - (UIView *)inputAccessoryView{ 186 | return nil; 187 | } 188 | 189 | - (void) keyboardWillHide:(NSNotification *)notif { 190 | [self hideToolbar]; 191 | } 192 | 193 | - (void) keyboardWillShow:(NSNotification *)notif { 194 | 195 | [[UIApplication sharedApplication].delegate.window bringSubviewToFront:self.toolbarView]; 196 | 197 | [self performSelector:@selector(removeBar) withObject:nil afterDelay:0.0f]; 198 | if (RK_IS_IPHONE) { 199 | if (isActiveResponder) 200 | [self showToolbar]; 201 | else 202 | [self hideToolbar]; 203 | return; 204 | } 205 | 206 | NSDictionary *dict = [notif userInfo]; 207 | CGFloat duration =[[dict objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]; 208 | CGPoint beginPoint = [[dict objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].origin; 209 | keyboardFrame = [[dict objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 210 | [self showToolbar]; 211 | 212 | if (isActiveResponder==NO) 213 | self.toolbarView.hidden = YES; 214 | 215 | CGRect aFrame = self.toolbarView.frame; 216 | aFrame.origin = beginPoint; 217 | self.toolbarView.frame = aFrame; 218 | 219 | UIInterfaceOrientation newOrientation = [UIApplication sharedApplication].statusBarOrientation; 220 | CGRect finalFrame = self.toolbarView.frame; 221 | switch (newOrientation) { 222 | // hardcoded - I know it is not good, but there are some artifacts on iOS 5, when hiding/showing keyboard multilpe times on richtextview 223 | case UIInterfaceOrientationLandscapeLeft: 224 | finalFrame= CGRectMake(372+10, 0, 34, 1024); 225 | break; 226 | case UIInterfaceOrientationLandscapeRight: 227 | finalFrame= CGRectMake(396-44, 0, 34, 1024); 228 | break; 229 | case UIInterfaceOrientationPortraitUpsideDown: 230 | finalFrame= CGRectMake(0, 308-44, 768, 34); 231 | break; 232 | default: 233 | finalFrame= CGRectMake(0, 716+10, 768, 34); 234 | break; 235 | } 236 | 237 | [UIView animateWithDuration:duration animations:^{ 238 | [self.toolbarView setFrame:finalFrame]; 239 | }]; 240 | 241 | } 242 | 243 | -(void) hideToolbar{ 244 | if (RK_IS_IPHONE){ 245 | if (isHiding) return; 246 | isHiding =YES; 247 | [UIView animateWithDuration:0.25 animations:^{ 248 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 249 | CGRect aFrame = self.toolbarView.frame; 250 | aFrame.origin = CGPointMake(0, screenHeight-34); 251 | self.toolbarView.frame = aFrame; 252 | } completion:^(BOOL finished) { 253 | NSLog(@"hide finished %i",finished); 254 | isHiding = NO; 255 | if (finished) 256 | self.toolbarView.hidden = YES; 257 | }]; 258 | return; 259 | } 260 | self.toolbarView.hidden = YES; 261 | [self.toolbarView removeFromSuperview]; 262 | } 263 | -(void) showToolbar{ 264 | if (RK_IS_IPHONE){ 265 | if (isShowing) return; 266 | isShowing = YES; 267 | CGRect aFrame = self.toolbarView.frame; 268 | aFrame.origin = CGPointMake(0, screenHeight-34); 269 | if (isHiding==NO) 270 | self.toolbarView.frame = aFrame; 271 | else 272 | [self.toolbarView.layer removeAllAnimations]; 273 | self.toolbarView.hidden = NO; 274 | [UIView animateWithDuration:0.25 animations:^{ 275 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 276 | CGRect aFrame = self.toolbarView.frame; 277 | aFrame.origin = CGPointMake(0, screenHeight-260 + 10); 278 | self.toolbarView.frame = aFrame; 279 | 280 | }completion:^(BOOL finished) { 281 | isShowing = NO; 282 | self.toolbarView.hidden = NO; 283 | }]; 284 | return; 285 | } 286 | [self.toolbarView removeFromSuperview]; 287 | self.toolbarView.hidden = NO; 288 | [[UIApplication sharedApplication].delegate.window addSubview:self.toolbarView]; 289 | 290 | UIInterfaceOrientation newOrientation = [UIApplication sharedApplication].statusBarOrientation; 291 | switch (newOrientation) { 292 | case UIInterfaceOrientationLandscapeLeft: 293 | rotate = CGAffineTransformMakeRotation(M_PI+M_PI_2); // 90 degress 294 | break; 295 | case UIInterfaceOrientationLandscapeRight: 296 | rotate = CGAffineTransformMakeRotation(M_PI_2); // 270 degrees 297 | break; 298 | case UIInterfaceOrientationPortraitUpsideDown: 299 | rotate = CGAffineTransformMakeRotation(M_PI); // 180 degrees 300 | break; 301 | default: 302 | rotate = CGAffineTransformMakeRotation(0.0); 303 | break; 304 | } 305 | [self.toolbarView setTransform:rotate]; 306 | } 307 | -(void) onFocusOut{ 308 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(richTextViewWillLooseFocus:)]) 309 | [[self aDelegate] richTextViewWillLooseFocus:self]; 310 | [self hideToolbar]; 311 | [self firstResponder:NO]; 312 | } 313 | -(void) onFocus{ 314 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(richTextViewWillReceiveFocus:)]) 315 | [[self aDelegate] richTextViewWillReceiveFocus:self]; 316 | [self firstResponder:YES]; 317 | self.toolbarView.hidden = NO; 318 | 319 | if (RK_IS_IPHONE){ 320 | if (isShowing==NO && self.toolbarView.frame.origin.y!=(screenHeight-260+10)){ 321 | [self showToolbar]; 322 | } 323 | } 324 | } 325 | -(void) touchEnded{ 326 | isActiveResponder = YES; 327 | } 328 | -(void) touchMoved{ 329 | if (isActiveResponder) 330 | [self checkSelections]; 331 | } 332 | 333 | +(BOOL)isFirstResponder:(UIView *)v{ 334 | for (UIView *vs in v.subviews) { 335 | if ([vs isFirstResponder] || [self isFirstResponder:vs]) { 336 | return YES; 337 | } 338 | } 339 | return NO; 340 | } 341 | -(BOOL)isFirstResponder{ 342 | return [[self class] isFirstResponder:self]; 343 | } 344 | 345 | -(void) firstResponder:(BOOL) f{ 346 | isActiveResponder = f; 347 | if (isActiveResponder){ 348 | [[NSNotificationCenter defaultCenter] postNotificationName:WRKRichTextViewWillBecomeFirstResponder object:self]; 349 | } 350 | } 351 | -(BOOL) becomeFirstResponder{ 352 | if ([self respondsToSelector:@selector(setKeyboardDisplayRequiresUserAction:)]) 353 | self.keyboardDisplayRequiresUserAction = NO; 354 | [self firstResponder:YES]; 355 | [self stringByEvaluatingJavaScriptFromString:@"document.getElementById('entryContents').focus();"]; 356 | [self showToolbar]; 357 | return [super becomeFirstResponder]; 358 | } 359 | -(BOOL)resignFirstResponder{ 360 | [[NSNotificationCenter defaultCenter] postNotificationName:WRKRichTextViewWillResignFirstResponder object:nil]; 361 | 362 | if (self.isTheOnlyRichTextView==NO){ 363 | UITextField *t = [[UITextField alloc] initWithFrame:self.toolbarView.frame]; 364 | [self.toolbarView.superview addSubview:t]; 365 | [t becomeFirstResponder]; 366 | [t resignFirstResponder]; 367 | [t removeFromSuperview]; 368 | [t release]; 369 | } 370 | [self stringByEvaluatingJavaScriptFromString:@"document.activeElement.blur()"]; 371 | [self hideToolbar]; 372 | [self firstResponder:NO]; 373 | 374 | return [super resignFirstResponder]; 375 | } 376 | -(void) setInputAccessoryView:(UIView *)inputAccessoryView{ 377 | 378 | } 379 | 380 | 381 | -(void)didChangeSegmentControl:(UISegmentedControl*)sender{ 382 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(prevNextControlTouched:)]){ 383 | [[NSNotificationCenter defaultCenter] postNotificationName:WRKRichTextViewWillBecomeFirstResponder object:self]; 384 | [[self aDelegate] prevNextControlTouched:sender]; 385 | } 386 | } 387 | -(void) willDidLoad{ 388 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(richTextViewDidLoad:)]) 389 | [[self aDelegate] richTextViewDidLoad:self]; 390 | [self checkSelections]; 391 | } 392 | -(void) willChangeHeight:(int)newHeight{ 393 | self.scalesPageToFit = YES; 394 | self.scrollView.scrollEnabled = NO; 395 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(richTextViewDidChange:)]) 396 | [[self aDelegate] richTextViewDidChange:self]; 397 | [self checkSelections]; 398 | } 399 | -(int)contentSizeHeight{ 400 | return [[self stringByEvaluatingJavaScriptFromString:@"getHeight()"] intValue]; 401 | } 402 | -(void) setMinimumHeight:(int)newHeight{ 403 | minHeight = newHeight; 404 | [self stopLoading]; 405 | [self setText:@""]; 406 | } 407 | -(NSString*) text{ 408 | NSString* t = [self stringByEvaluatingJavaScriptFromString:@"document.getElementById('entryContents').innerHTML"]; 409 | 410 | 411 | t = [t stringByReplacingOccurrencesOfString:@"
" withString:@"
"]; 412 | t = [t stringByReplacingOccurrencesOfString:@"
" withString:@""]; 413 | 414 | NSArray *stringsToRemove = [NSArray arrayWithObjects: 415 | @" ", 416 | @" ", 417 | @"
", 418 | @"
", 419 | @"
", 420 | nil]; 421 | NSString *t2 = t; 422 | for (NSString *s in stringsToRemove) 423 | t2 = [t2 stringByReplacingOccurrencesOfString:s withString:@""]; 424 | if ([t2 length] == 0 ){ 425 | return @""; 426 | } 427 | 428 | 429 | return t; 430 | } 431 | -(void)setText:(NSString *)richText{ 432 | if (richText==nil) richText = @""; 433 | 434 | NSBundle *bundle = [NSBundle mainBundle]; 435 | NSURL *indexFileURL = [bundle URLForResource:@"RKRichTextView" withExtension:@"html"]; 436 | NSString *text = [NSString stringWithContentsOfURL:indexFileURL encoding:NSUTF8StringEncoding error:nil]; 437 | 438 | text = [text stringByReplacingOccurrencesOfString:@"73px;" withString:[NSString stringWithFormat:@"%dpx;",minHeight]]; 439 | 440 | text = [text stringByReplacingOccurrencesOfString:@"{%content}" withString:richText]; 441 | 442 | 443 | [self loadHTMLString:text baseURL:nil]; 444 | self.scalesPageToFit = YES; 445 | self.scrollView.scrollEnabled = NO; 446 | for(UIView *wview in [[[self subviews] objectAtIndex:0] subviews]) { 447 | if([wview isKindOfClass:[UIImageView class]]) { wview.hidden = YES; } 448 | } 449 | } 450 | - (IBAction)boldAction:(id)sender { 451 | [self stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"Bold\")"]; 452 | [self checkSelections]; 453 | } 454 | 455 | - (IBAction)italicAction:(id)sender { 456 | [self stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"Italic\")"]; 457 | [self checkSelections]; 458 | } 459 | 460 | - (IBAction)underlineAction:(id)sender { 461 | [self stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"underline\")"]; 462 | [self checkSelections]; 463 | } 464 | - (IBAction)strikeAction:(id)sender { 465 | [self stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"strikeThrough\")"]; 466 | [self checkSelections]; 467 | } 468 | 469 | - (IBAction)orderedAction:(id)sender { 470 | [self stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"insertOrderedList\")"]; 471 | [self checkSelections]; 472 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(richTextViewDidChange:)]) 473 | [[self aDelegate] richTextViewDidChange:self]; 474 | } 475 | - (IBAction)unorderedAction:(id)sender { 476 | [self stringByEvaluatingJavaScriptFromString:@"document.execCommand(\"insertUnorderedList\")"]; 477 | [self checkSelections]; 478 | if ([((NSObject*)[self aDelegate]) respondsToSelector:@selector(richTextViewDidChange:)]) 479 | [[self aDelegate] richTextViewDidChange:self]; 480 | } 481 | -(void) checkSelections{ 482 | 483 | BOOL boldEnabled = [[self stringByEvaluatingJavaScriptFromString:@"document.queryCommandState('Bold')"] boolValue]; 484 | BOOL italicEnabled = [[self stringByEvaluatingJavaScriptFromString:@"document.queryCommandState('Italic')"] boolValue]; 485 | BOOL underlineEnabled = [[self stringByEvaluatingJavaScriptFromString:@"document.queryCommandState('Underline')"] boolValue]; 486 | BOOL strikeEnabled = [[self stringByEvaluatingJavaScriptFromString:@"document.queryCommandState('strikeThrough')"] boolValue]; 487 | BOOL isOrdered = [[self stringByEvaluatingJavaScriptFromString:@"document.queryCommandState('insertOrderedList')"] boolValue]; 488 | BOOL isUnordered = [[self stringByEvaluatingJavaScriptFromString:@"document.queryCommandState('insertUnorderedList')"] boolValue]; 489 | 490 | UIColor *blue = [UIColor colorWithRed:0.2 green:0.5 blue:0.75 alpha:1.0]; 491 | UIColor *clear = [UIColor colorWithRed:95.0f/255.0f green:97.0f/255.0f blue:106.0f/255.0f alpha:1.0f]; 492 | 493 | if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { 494 | for (UIBarButtonItem *item in self.toolbar.items){ 495 | if (item.tag==1) 496 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName: (boldEnabled?_selectedColor:_deselectedColor)} forState:UIControlStateNormal]; 497 | else if (item.tag==2) 498 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName: (italicEnabled?_selectedColor:_deselectedColor)} forState:UIControlStateNormal]; 499 | else if (item.tag==3) 500 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName: (underlineEnabled?_selectedColor:_deselectedColor)} forState:UIControlStateNormal]; 501 | else if (item.tag==4) 502 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName: (strikeEnabled?_selectedColor:_deselectedColor)} forState:UIControlStateNormal]; 503 | else if (item.tag==5) 504 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName: (isOrdered?_selectedColor:_deselectedColor)} forState:UIControlStateNormal]; 505 | else if (item.tag==6) 506 | [item setTitleTextAttributes:@{NSForegroundColorAttributeName: (isUnordered?_selectedColor:_deselectedColor)} forState:UIControlStateNormal]; 507 | } 508 | } else { 509 | for (UIBarButtonItem *item in self.toolbar.items){ 510 | if (item.tag==1) 511 | [item setTintColor:boldEnabled?blue:clear]; 512 | else if (item.tag==2) 513 | [item setTintColor:italicEnabled?blue:clear]; 514 | else if (item.tag==3) 515 | [item setTintColor:underlineEnabled?blue:clear]; 516 | else if (item.tag==4) 517 | [item setTintColor:strikeEnabled?blue:clear]; 518 | else if (item.tag==5) 519 | [item setTintColor:isOrdered?blue:clear]; 520 | else if (item.tag==6) 521 | [item setTintColor:isUnordered?blue:clear]; 522 | } 523 | } 524 | } 525 | 526 | -(UIWindow*) keyWindow{ 527 | for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { 528 | if (![[testWindow class] isEqual:[UIWindow class]]) { 529 | return testWindow; 530 | } 531 | } 532 | return nil; 533 | } 534 | - (void)removeBar { 535 | 536 | // Locate non-UIWindow. 537 | UIWindow *keyboardWindow = nil; 538 | for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { 539 | if (![[testWindow class] isEqual:[UIWindow class]]) { 540 | keyboardWindow = testWindow; 541 | break; 542 | } 543 | } 544 | 545 | // Locate UIWebFormView. 546 | for (UIView *formView in [keyboardWindow subviews]) { 547 | // iOS 5 sticks the UIWebFormView inside a UIPeripheralHostView. 548 | if ([[formView description] rangeOfString:@"UIPeripheralHostView"].location != NSNotFound) { 549 | for (UIView *subView in [formView subviews]) { 550 | if ([[subView description] rangeOfString:@"UIWebFormAccessory"].location != NSNotFound) { 551 | // remove the input accessory view 552 | [subView setHidden:YES]; 553 | [subView removeFromSuperview]; 554 | } 555 | else if([[subView description] rangeOfString:@"UIImageView"].location != NSNotFound){ 556 | // remove the line above the input accessory view (changing the frame) 557 | [subView setHidden:YES]; 558 | [subView setFrame:CGRectZero]; 559 | } 560 | } 561 | } 562 | } 563 | } 564 | 565 | #pragma mark - Method swizzle for fix iOS 7 566 | 567 | - (void)swizzleMethod 568 | { 569 | if (!_isAlreadySwizzle) { 570 | _isAlreadySwizzle = YES; 571 | if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { 572 | [self __removeInputAccessoryView]; 573 | return; 574 | } 575 | } 576 | } 577 | 578 | -(void)__removeInputAccessoryView 579 | { 580 | UIView* subview; 581 | 582 | for (UIView* view in self.scrollView.subviews) { 583 | if([[view.class description] hasPrefix:@"UIWeb"]) 584 | subview = view; 585 | } 586 | 587 | if(subview == nil) return; 588 | 589 | NSString* name = [NSString stringWithFormat:@"%@_SwizzleAccessoryViewRemover", subview.class.superclass]; 590 | Class newClass = NSClassFromString(name); 591 | 592 | if(newClass == nil) 593 | { 594 | newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0); 595 | if(!newClass) return; 596 | 597 | Method method = class_getInstanceMethod([_SwizzleAccessoryViewRemover class], @selector(inputAccessoryView)); 598 | class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)); 599 | 600 | objc_registerClassPair(newClass); 601 | } 602 | 603 | object_setClass(subview, newClass); 604 | } 605 | 606 | @end 607 | -------------------------------------------------------------------------------- /RKRichTextView/RKRichTextViewListener.h: -------------------------------------------------------------------------------- 1 | // 2 | // RichTextDelegateListener.h 3 | // 4 | // Created by ren6 on 2/4/13. 5 | // 6 | 7 | #import 8 | #import "RKRichTextView.h" 9 | @class RKRichTextView; 10 | @interface RKRichTextViewListener : NSObject 11 | @property (nonatomic, assign) RKRichTextView* richTextView; 12 | @end 13 | -------------------------------------------------------------------------------- /RKRichTextView/RKRichTextViewListener.m: -------------------------------------------------------------------------------- 1 | // 2 | // RichTextDelegateListener.m 3 | // 4 | // Created by ren6 on 2/4/13. 5 | // 6 | 7 | #import "RKRichTextViewListener.h" 8 | @interface RKRichTextView() 9 | -(void) willChangeHeight:(int)newHeight; 10 | -(void) willDidLoad; 11 | -(void) onFocus; 12 | -(void) onFocusOut; 13 | -(void) touchEnded; 14 | -(void) touchMoved; 15 | @end 16 | @implementation RKRichTextViewListener 17 | -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 18 | 19 | NSString *string = request.URL.absoluteString; 20 | if ([string rangeOfString:@"focusout"].location!=NSNotFound){ 21 | [self.richTextView onFocusOut]; 22 | return NO; 23 | } else if ([string rangeOfString:@"focusin"].location!=NSNotFound){ 24 | [self.richTextView onFocus]; 25 | return NO; 26 | } else if ([string rangeOfString:@"touchmove"].location!=NSNotFound){ 27 | [self.richTextView touchMoved]; 28 | return NO; 29 | } else if ([string rangeOfString:@"touchend"].location!=NSNotFound){ 30 | [self.richTextView touchEnded]; 31 | return NO; 32 | } else if ([string rangeOfString:@"touchstart"].location!=NSNotFound){ 33 | return NO; 34 | } 35 | string = [string stringByReplacingOccurrencesOfString:@"http://" withString:@""]; 36 | string = [string stringByReplacingOccurrencesOfString:@".ru/" withString:@""]; 37 | int height = [string intValue]; 38 | if (height>0){ 39 | [self.richTextView willChangeHeight:height]; 40 | return NO; 41 | } 42 | return YES; 43 | } 44 | -(void)webViewDidFinishLoad:(RKRichTextView *)webView{ 45 | [self.richTextView willDidLoad]; 46 | } 47 | @end 48 | -------------------------------------------------------------------------------- /RKRichTextView/RKRichTextViewToolbar.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8485ADFB16C8E1E600C8065E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8485ADFA16C8E1E600C8065E /* UIKit.framework */; }; 11 | 8485ADFD16C8E1E600C8065E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8485ADFC16C8E1E600C8065E /* Foundation.framework */; }; 12 | 8485ADFF16C8E1E600C8065E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8485ADFE16C8E1E600C8065E /* CoreGraphics.framework */; }; 13 | 8485AE0516C8E1E600C8065E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE0316C8E1E600C8065E /* InfoPlist.strings */; }; 14 | 8485AE0716C8E1E600C8065E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8485AE0616C8E1E600C8065E /* main.m */; }; 15 | 8485AE0B16C8E1E600C8065E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8485AE0A16C8E1E600C8065E /* AppDelegate.m */; }; 16 | 8485AE0D16C8E1E600C8065E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE0C16C8E1E600C8065E /* Default.png */; }; 17 | 8485AE0F16C8E1E600C8065E /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE0E16C8E1E600C8065E /* Default@2x.png */; }; 18 | 8485AE1116C8E1E600C8065E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE1016C8E1E600C8065E /* Default-568h@2x.png */; }; 19 | 8485AE1416C8E1E600C8065E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8485AE1316C8E1E600C8065E /* ViewController.m */; }; 20 | 8485AE1716C8E1E600C8065E /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE1516C8E1E600C8065E /* ViewController_iPhone.xib */; }; 21 | 8485AE1A16C8E1E600C8065E /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE1816C8E1E600C8065E /* ViewController_iPad.xib */; }; 22 | 8485AE2716C8E20D00C8065E /* RKRichTextView.html in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE2216C8E20D00C8065E /* RKRichTextView.html */; }; 23 | 8485AE2816C8E20D00C8065E /* RKRichTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8485AE2316C8E20D00C8065E /* RKRichTextView.m */; }; 24 | 8485AE2916C8E20D00C8065E /* RKRichTextViewListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 8485AE2516C8E20D00C8065E /* RKRichTextViewListener.m */; }; 25 | 8485AE2A16C8E20D00C8065E /* RKRichTextViewToolbar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8485AE2616C8E20D00C8065E /* RKRichTextViewToolbar.xib */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 8485ADF716C8E1E600C8065E /* RichTextViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RichTextViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 8485ADFA16C8E1E600C8065E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 31 | 8485ADFC16C8E1E600C8065E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 32 | 8485ADFE16C8E1E600C8065E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 33 | 8485AE0216C8E1E600C8065E /* RichTextViewDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RichTextViewDemo-Info.plist"; sourceTree = ""; }; 34 | 8485AE0416C8E1E600C8065E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 35 | 8485AE0616C8E1E600C8065E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 36 | 8485AE0816C8E1E600C8065E /* RichTextViewDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RichTextViewDemo-Prefix.pch"; sourceTree = ""; }; 37 | 8485AE0916C8E1E600C8065E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 38 | 8485AE0A16C8E1E600C8065E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 39 | 8485AE0C16C8E1E600C8065E /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 40 | 8485AE0E16C8E1E600C8065E /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 41 | 8485AE1016C8E1E600C8065E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 42 | 8485AE1216C8E1E600C8065E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 43 | 8485AE1316C8E1E600C8065E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 44 | 8485AE1616C8E1E600C8065E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; 45 | 8485AE1916C8E1E600C8065E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; 46 | 8485AE2116C8E20D00C8065E /* RKRichTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRichTextView.h; sourceTree = ""; }; 47 | 8485AE2216C8E20D00C8065E /* RKRichTextView.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = RKRichTextView.html; sourceTree = ""; }; 48 | 8485AE2316C8E20D00C8065E /* RKRichTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRichTextView.m; sourceTree = ""; }; 49 | 8485AE2416C8E20D00C8065E /* RKRichTextViewListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRichTextViewListener.h; sourceTree = ""; }; 50 | 8485AE2516C8E20D00C8065E /* RKRichTextViewListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRichTextViewListener.m; sourceTree = ""; }; 51 | 8485AE2616C8E20D00C8065E /* RKRichTextViewToolbar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RKRichTextViewToolbar.xib; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 8485ADF416C8E1E600C8065E /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 8485ADFB16C8E1E600C8065E /* UIKit.framework in Frameworks */, 60 | 8485ADFD16C8E1E600C8065E /* Foundation.framework in Frameworks */, 61 | 8485ADFF16C8E1E600C8065E /* CoreGraphics.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 8485ADEE16C8E1E600C8065E = { 69 | isa = PBXGroup; 70 | children = ( 71 | 8485AE2016C8E20D00C8065E /* RKRichTextView */, 72 | 8485AE0016C8E1E600C8065E /* RichTextViewDemo */, 73 | 8485ADF916C8E1E600C8065E /* Frameworks */, 74 | 8485ADF816C8E1E600C8065E /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 8485ADF816C8E1E600C8065E /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 8485ADF716C8E1E600C8065E /* RichTextViewDemo.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 8485ADF916C8E1E600C8065E /* Frameworks */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 8485ADFA16C8E1E600C8065E /* UIKit.framework */, 90 | 8485ADFC16C8E1E600C8065E /* Foundation.framework */, 91 | 8485ADFE16C8E1E600C8065E /* CoreGraphics.framework */, 92 | ); 93 | name = Frameworks; 94 | sourceTree = ""; 95 | }; 96 | 8485AE0016C8E1E600C8065E /* RichTextViewDemo */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 8485AE0916C8E1E600C8065E /* AppDelegate.h */, 100 | 8485AE0A16C8E1E600C8065E /* AppDelegate.m */, 101 | 8485AE1216C8E1E600C8065E /* ViewController.h */, 102 | 8485AE1316C8E1E600C8065E /* ViewController.m */, 103 | 8485AE1516C8E1E600C8065E /* ViewController_iPhone.xib */, 104 | 8485AE1816C8E1E600C8065E /* ViewController_iPad.xib */, 105 | 8485AE0116C8E1E600C8065E /* Supporting Files */, 106 | ); 107 | path = RichTextViewDemo; 108 | sourceTree = ""; 109 | }; 110 | 8485AE0116C8E1E600C8065E /* Supporting Files */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 8485AE0216C8E1E600C8065E /* RichTextViewDemo-Info.plist */, 114 | 8485AE0316C8E1E600C8065E /* InfoPlist.strings */, 115 | 8485AE0616C8E1E600C8065E /* main.m */, 116 | 8485AE0816C8E1E600C8065E /* RichTextViewDemo-Prefix.pch */, 117 | 8485AE0C16C8E1E600C8065E /* Default.png */, 118 | 8485AE0E16C8E1E600C8065E /* Default@2x.png */, 119 | 8485AE1016C8E1E600C8065E /* Default-568h@2x.png */, 120 | ); 121 | name = "Supporting Files"; 122 | sourceTree = ""; 123 | }; 124 | 8485AE2016C8E20D00C8065E /* RKRichTextView */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 8485AE2116C8E20D00C8065E /* RKRichTextView.h */, 128 | 8485AE2316C8E20D00C8065E /* RKRichTextView.m */, 129 | 8485AE2416C8E20D00C8065E /* RKRichTextViewListener.h */, 130 | 8485AE2516C8E20D00C8065E /* RKRichTextViewListener.m */, 131 | 8485AE2216C8E20D00C8065E /* RKRichTextView.html */, 132 | 8485AE2616C8E20D00C8065E /* RKRichTextViewToolbar.xib */, 133 | ); 134 | path = RKRichTextView; 135 | sourceTree = ""; 136 | }; 137 | /* End PBXGroup section */ 138 | 139 | /* Begin PBXNativeTarget section */ 140 | 8485ADF616C8E1E600C8065E /* RichTextViewDemo */ = { 141 | isa = PBXNativeTarget; 142 | buildConfigurationList = 8485AE1D16C8E1E600C8065E /* Build configuration list for PBXNativeTarget "RichTextViewDemo" */; 143 | buildPhases = ( 144 | 8485ADF316C8E1E600C8065E /* Sources */, 145 | 8485ADF416C8E1E600C8065E /* Frameworks */, 146 | 8485ADF516C8E1E600C8065E /* Resources */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = RichTextViewDemo; 153 | productName = RichTextViewDemo; 154 | productReference = 8485ADF716C8E1E600C8065E /* RichTextViewDemo.app */; 155 | productType = "com.apple.product-type.application"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | 8485ADEF16C8E1E600C8065E /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | LastUpgradeCheck = 0460; 164 | ORGANIZATIONNAME = ren6; 165 | }; 166 | buildConfigurationList = 8485ADF216C8E1E600C8065E /* Build configuration list for PBXProject "RichTextViewDemo" */; 167 | compatibilityVersion = "Xcode 3.2"; 168 | developmentRegion = English; 169 | hasScannedForEncodings = 0; 170 | knownRegions = ( 171 | en, 172 | ); 173 | mainGroup = 8485ADEE16C8E1E600C8065E; 174 | productRefGroup = 8485ADF816C8E1E600C8065E /* Products */; 175 | projectDirPath = ""; 176 | projectRoot = ""; 177 | targets = ( 178 | 8485ADF616C8E1E600C8065E /* RichTextViewDemo */, 179 | ); 180 | }; 181 | /* End PBXProject section */ 182 | 183 | /* Begin PBXResourcesBuildPhase section */ 184 | 8485ADF516C8E1E600C8065E /* Resources */ = { 185 | isa = PBXResourcesBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | 8485AE0516C8E1E600C8065E /* InfoPlist.strings in Resources */, 189 | 8485AE0D16C8E1E600C8065E /* Default.png in Resources */, 190 | 8485AE0F16C8E1E600C8065E /* Default@2x.png in Resources */, 191 | 8485AE1116C8E1E600C8065E /* Default-568h@2x.png in Resources */, 192 | 8485AE1716C8E1E600C8065E /* ViewController_iPhone.xib in Resources */, 193 | 8485AE1A16C8E1E600C8065E /* ViewController_iPad.xib in Resources */, 194 | 8485AE2716C8E20D00C8065E /* RKRichTextView.html in Resources */, 195 | 8485AE2A16C8E20D00C8065E /* RKRichTextViewToolbar.xib in Resources */, 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | }; 199 | /* End PBXResourcesBuildPhase section */ 200 | 201 | /* Begin PBXSourcesBuildPhase section */ 202 | 8485ADF316C8E1E600C8065E /* Sources */ = { 203 | isa = PBXSourcesBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | 8485AE0716C8E1E600C8065E /* main.m in Sources */, 207 | 8485AE0B16C8E1E600C8065E /* AppDelegate.m in Sources */, 208 | 8485AE1416C8E1E600C8065E /* ViewController.m in Sources */, 209 | 8485AE2816C8E20D00C8065E /* RKRichTextView.m in Sources */, 210 | 8485AE2916C8E20D00C8065E /* RKRichTextViewListener.m in Sources */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXSourcesBuildPhase section */ 215 | 216 | /* Begin PBXVariantGroup section */ 217 | 8485AE0316C8E1E600C8065E /* InfoPlist.strings */ = { 218 | isa = PBXVariantGroup; 219 | children = ( 220 | 8485AE0416C8E1E600C8065E /* en */, 221 | ); 222 | name = InfoPlist.strings; 223 | sourceTree = ""; 224 | }; 225 | 8485AE1516C8E1E600C8065E /* ViewController_iPhone.xib */ = { 226 | isa = PBXVariantGroup; 227 | children = ( 228 | 8485AE1616C8E1E600C8065E /* en */, 229 | ); 230 | name = ViewController_iPhone.xib; 231 | sourceTree = ""; 232 | }; 233 | 8485AE1816C8E1E600C8065E /* ViewController_iPad.xib */ = { 234 | isa = PBXVariantGroup; 235 | children = ( 236 | 8485AE1916C8E1E600C8065E /* en */, 237 | ); 238 | name = ViewController_iPad.xib; 239 | sourceTree = ""; 240 | }; 241 | /* End PBXVariantGroup section */ 242 | 243 | /* Begin XCBuildConfiguration section */ 244 | 8485AE1B16C8E1E600C8065E /* Debug */ = { 245 | isa = XCBuildConfiguration; 246 | buildSettings = { 247 | ALWAYS_SEARCH_USER_PATHS = NO; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_EMPTY_BODY = YES; 252 | CLANG_WARN_ENUM_CONVERSION = YES; 253 | CLANG_WARN_INT_CONVERSION = YES; 254 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 255 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 256 | COPY_PHASE_STRIP = NO; 257 | GCC_C_LANGUAGE_STANDARD = gnu99; 258 | GCC_DYNAMIC_NO_PIC = NO; 259 | GCC_OPTIMIZATION_LEVEL = 0; 260 | GCC_PREPROCESSOR_DEFINITIONS = ( 261 | "DEBUG=1", 262 | "$(inherited)", 263 | ); 264 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 265 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 266 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 267 | GCC_WARN_UNUSED_VARIABLE = YES; 268 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 269 | ONLY_ACTIVE_ARCH = YES; 270 | SDKROOT = iphoneos; 271 | TARGETED_DEVICE_FAMILY = "1,2"; 272 | }; 273 | name = Debug; 274 | }; 275 | 8485AE1C16C8E1E600C8065E /* Release */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ALWAYS_SEARCH_USER_PATHS = NO; 279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 280 | CLANG_CXX_LIBRARY = "libc++"; 281 | CLANG_WARN_CONSTANT_CONVERSION = YES; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 286 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 287 | COPY_PHASE_STRIP = YES; 288 | GCC_C_LANGUAGE_STANDARD = gnu99; 289 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 290 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 291 | GCC_WARN_UNUSED_VARIABLE = YES; 292 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 293 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 294 | SDKROOT = iphoneos; 295 | TARGETED_DEVICE_FAMILY = "1,2"; 296 | VALIDATE_PRODUCT = YES; 297 | }; 298 | name = Release; 299 | }; 300 | 8485AE1E16C8E1E600C8065E /* Debug */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | CODE_SIGN_IDENTITY = ""; 304 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 305 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 306 | GCC_PREFIX_HEADER = "RichTextViewDemo/RichTextViewDemo-Prefix.pch"; 307 | INFOPLIST_FILE = "RichTextViewDemo/RichTextViewDemo-Info.plist"; 308 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 309 | PRODUCT_NAME = "$(TARGET_NAME)"; 310 | TARGETED_DEVICE_FAMILY = "1,2"; 311 | WRAPPER_EXTENSION = app; 312 | }; 313 | name = Debug; 314 | }; 315 | 8485AE1F16C8E1E600C8065E /* Release */ = { 316 | isa = XCBuildConfiguration; 317 | buildSettings = { 318 | CODE_SIGN_IDENTITY = ""; 319 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 320 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 321 | GCC_PREFIX_HEADER = "RichTextViewDemo/RichTextViewDemo-Prefix.pch"; 322 | INFOPLIST_FILE = "RichTextViewDemo/RichTextViewDemo-Info.plist"; 323 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 324 | PRODUCT_NAME = "$(TARGET_NAME)"; 325 | TARGETED_DEVICE_FAMILY = "1,2"; 326 | WRAPPER_EXTENSION = app; 327 | }; 328 | name = Release; 329 | }; 330 | /* End XCBuildConfiguration section */ 331 | 332 | /* Begin XCConfigurationList section */ 333 | 8485ADF216C8E1E600C8065E /* Build configuration list for PBXProject "RichTextViewDemo" */ = { 334 | isa = XCConfigurationList; 335 | buildConfigurations = ( 336 | 8485AE1B16C8E1E600C8065E /* Debug */, 337 | 8485AE1C16C8E1E600C8065E /* Release */, 338 | ); 339 | defaultConfigurationIsVisible = 0; 340 | defaultConfigurationName = Release; 341 | }; 342 | 8485AE1D16C8E1E600C8065E /* Build configuration list for PBXNativeTarget "RichTextViewDemo" */ = { 343 | isa = XCConfigurationList; 344 | buildConfigurations = ( 345 | 8485AE1E16C8E1E600C8065E /* Debug */, 346 | 8485AE1F16C8E1E600C8065E /* Release */, 347 | ); 348 | defaultConfigurationIsVisible = 0; 349 | defaultConfigurationName = Release; 350 | }; 351 | /* End XCConfigurationList section */ 352 | }; 353 | rootObject = 8485ADEF16C8E1E600C8065E /* Project object */; 354 | } 355 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/project.xcworkspace/xcshareddata/RichTextViewDemo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 8B1089E4-5160-4EAB-B02B-FBC1197D49FF 9 | IDESourceControlProjectName 10 | RichTextViewDemo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | FAB3E7DD-4463-4B78-9561-EF43E1FC6E4C 14 | ssh://github.com/ren6/RKRichTextView.git 15 | 16 | IDESourceControlProjectPath 17 | RichTextViewDemo.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | FAB3E7DD-4463-4B78-9561-EF43E1FC6E4C 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/ren6/RKRichTextView.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | FAB3E7DD-4463-4B78-9561-EF43E1FC6E4C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | FAB3E7DD-4463-4B78-9561-EF43E1FC6E4C 36 | IDESourceControlWCCName 37 | RKRichTextView 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/RichTextViewDemo.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/project.xcworkspace/xcuserdata/renat.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/RichTextViewDemo.xcodeproj/project.xcworkspace/xcuserdata/renat.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/xcuserdata/admin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/RichTextViewDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RichTextViewDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8485ADF616C8E1E600C8065E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/xcuserdata/renat.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/xcuserdata/renat.xcuserdatad/xcschemes/RichTextViewDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /RichTextViewDemo.xcodeproj/xcuserdata/renat.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RichTextViewDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8485ADF616C8E1E600C8065E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /RichTextViewDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // RichTextViewDemo 4 | // 5 | // Created by ren6 on 2/11/13. 6 | // Copyright (c) 2013 ren6. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ViewController; 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) ViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /RichTextViewDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // RichTextViewDemo 4 | // 5 | // Created by ren6 on 2/11/13. 6 | // Copyright (c) 2013 ren6. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | #import "ViewController.h" 12 | 13 | @implementation AppDelegate 14 | 15 | - (void)dealloc 16 | { 17 | [_window release]; 18 | [_viewController release]; 19 | [super dealloc]; 20 | } 21 | 22 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 23 | { 24 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 25 | // Override point for customization after application launch. 26 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 27 | self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil] autorelease]; 28 | } else { 29 | self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil] autorelease]; 30 | } 31 | self.window.rootViewController = self.viewController; 32 | [self.window makeKeyAndVisible]; 33 | return YES; 34 | } 35 | 36 | - (void)applicationWillResignActive:(UIApplication *)application 37 | { 38 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 39 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 40 | } 41 | 42 | - (void)applicationDidEnterBackground:(UIApplication *)application 43 | { 44 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 45 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 46 | } 47 | 48 | - (void)applicationWillEnterForeground:(UIApplication *)application 49 | { 50 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 51 | } 52 | 53 | - (void)applicationDidBecomeActive:(UIApplication *)application 54 | { 55 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /RichTextViewDemo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/RichTextViewDemo/Default-568h@2x.png -------------------------------------------------------------------------------- /RichTextViewDemo/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/RichTextViewDemo/Default.png -------------------------------------------------------------------------------- /RichTextViewDemo/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/RichTextViewDemo/Default@2x.png -------------------------------------------------------------------------------- /RichTextViewDemo/RichTextViewDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | farcom.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /RichTextViewDemo/RichTextViewDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'RichTextViewDemo' target in the 'RichTextViewDemo' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /RichTextViewDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // RichTextViewDemo 4 | // 5 | // Created by ren6 on 2/11/13. 6 | // Copyright (c) 2013 ren6. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /RichTextViewDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // RichTextViewDemo 4 | // 5 | // Created by ren6 on 2/11/13. 6 | // Copyright (c) 2013 ren6. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "RKRichTextView.h" 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewWillAppear:(BOOL)animated 18 | { 19 | [super viewWillAppear:animated]; 20 | RKRichTextView *richTextView = [[[RKRichTextView alloc] initWithFrame:CGRectMake(20, 40, self.view.frame.size.width-40, 200)] autorelease]; 21 | richTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth; 22 | [self.view addSubview:richTextView]; 23 | richTextView.text = @"This is rich text!"; 24 | richTextView.aDelegate = self; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /RichTextViewDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /RichTextViewDemo/en.lproj/ViewController_iPad.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12C54 6 | 3084 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBIPadFramework 28 | 29 | 30 | IBFirstResponder 31 | IBIPadFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {768, 1004}} 37 | 38 | 39 | 40 | 1 41 | MC44NTA5ODAzOTIyIDAuODUwOTgwMzkyMiAwLjg1MDk4MDM5MjIAA 42 | 43 | 44 | 2 45 | 46 | IBIPadFramework 47 | 48 | 49 | 50 | 51 | 52 | 53 | view 54 | 55 | 56 | 57 | 3 58 | 59 | 60 | 61 | 62 | 63 | 0 64 | 65 | 66 | 67 | 68 | 69 | -1 70 | 71 | 72 | File's Owner 73 | 74 | 75 | -2 76 | 77 | 78 | 79 | 80 | 2 81 | 82 | 83 | 84 | 85 | 86 | 87 | ViewController 88 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 89 | UIResponder 90 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 91 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 92 | 93 | 94 | 95 | 96 | 97 | 3 98 | 99 | 100 | 101 | 102 | ViewController 103 | UIViewController 104 | 105 | IBProjectSource 106 | ./Classes/ViewController.h 107 | 108 | 109 | 110 | 111 | 0 112 | IBIPadFramework 113 | YES 114 | 3 115 | YES 116 | 2083 117 | 118 | 119 | -------------------------------------------------------------------------------- /RichTextViewDemo/en.lproj/ViewController_iPhone.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12C54 6 | 3084 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {320, 548}} 37 | 38 | 39 | 1 40 | MC44NTA5ODAzOTIyIDAuODUwOTgwMzkyMiAwLjg1MDk4MDM5MjIAA 41 | 42 | NO 43 | 44 | 45 | IBUIScreenMetrics 46 | 47 | YES 48 | 49 | 50 | 51 | 52 | 53 | {320, 568} 54 | {568, 320} 55 | 56 | 57 | IBCocoaTouchFramework 58 | Retina 4 Full Screen 59 | 2 60 | 61 | IBCocoaTouchFramework 62 | 63 | 64 | 65 | 66 | 67 | 68 | view 69 | 70 | 71 | 72 | 7 73 | 74 | 75 | 76 | 77 | 78 | 0 79 | 80 | 81 | 82 | 83 | 84 | -1 85 | 86 | 87 | File's Owner 88 | 89 | 90 | -2 91 | 92 | 93 | 94 | 95 | 6 96 | 97 | 98 | 99 | 100 | 101 | 102 | ViewController 103 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 104 | UIResponder 105 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 106 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 107 | 108 | 109 | 110 | 111 | 112 | 7 113 | 114 | 115 | 0 116 | IBCocoaTouchFramework 117 | YES 118 | 3 119 | YES 120 | 2083 121 | 122 | 123 | -------------------------------------------------------------------------------- /RichTextViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // RichTextViewDemo 4 | // 5 | // Created by ren6 on 2/11/13. 6 | // Copyright (c) 2013 ren6. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /config_version.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/config_version.txt -------------------------------------------------------------------------------- /config_version2.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/config_version2.txt -------------------------------------------------------------------------------- /config_version3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/config_version3.txt -------------------------------------------------------------------------------- /screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ren6/RKRichTextView/2996669b94b52fe1bf46967ba53121ab018d6051/screen.png --------------------------------------------------------------------------------