Cada nueva línea agrega una list numerada UITextView

Estoy intentando agregar un número al comienzo de cada fila cada vez que el usuario ingresa una nueva línea. Me gustaría que los numbers vayan en order (como en una list orderada), pero con mi código actual, si el usuario no agrega una nueva línea al final, sino que agrega la línea en el medio de UITextView , continúe contando desde donde lo dejó en la parte inferior, lo que significa que NSUInteger I realizó incrementos y no tiene en count que el usuario no hizo la nueva línea al final.

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { if ([text isEqualToString:@"\n"]) { numbenetworking ++; NSString *string = [NSString stringWithFormat:@"\n%lu ", (unsigned long)numbenetworking]; [self insertXEveryNewLine:range :textView :string]; return NO; } return YES; } - (BOOL)insertXEveryNewLine:(NSRange)place :(UITextView *)View :(NSString *)something { NSRange cursor = NSMakeRange(place.location + 3, 0); NSMutableString *mutableT = [NSMutableString stringWithString:View.text]; [mutableT insertString:something atIndex:place.location]; [View setText:mutableT]; return NO; } 

El código que acabo de publicar agrega una list numerada que aumenta en 1 cada línea nueva. Ahora, si intenta agregar una nueva línea en el medio, no al final, boostá en 1 desde el último número de línea, no boostá desde el número de línea anterior. Por ejemplo, si el usuario agrega 6 líneas a UITextView , el usuario va a la línea # 3 y agrega una nueva línea, mostrará # 7 después de la línea # 3, porque cada vez que el usuario crea una nueva línea se incrementa por 1.

Editar

introduzca la descripción de la imagen aquí

Cuando el usuario agrega una nueva línea después de la línea 1, quiero que todas las líneas se actualicen. Espero que esto sea más claro.

Este escenario es en realidad más complejo desde el punto de vista logístico que lo que había anticipado porque crear dinámicamente una list numerada en la input del usuario requiere un código que maneje muchos diversos escenarios relacionados con la eliminación, las inserciones, la position del cursor, etc. Pero en el centro de mi respuesta, esto el código funciona básicamente al separar la cadena de vista de text en componentes de "línea" separados por "\ n", elimina los numbers finales de cada línea, vuelve a agregar los numbers apropiados en order y luego recombina la cadena para volver a la vista de text .

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { // Add "1" when the user starts typing into the text field if (range.location == 0 && textView.text.length == 0) { // If the user simply presses enter, ignore the newline // entry, but add "1" to the start of the line. if ([text isEqualToString:@"\n"]) { [textView setText:@"1 "]; NSRange cursor = NSMakeRange(range.location + 3, 0); textView.selectedRange = cursor; return NO; } // In all other scenarios, append the replacement text. else { [textView setText:[NSString stringWithFormat:@"1 %@", text]]; } } // goBackOneLine is a Boolean to indicate whether the cursor // should go back 1 line; set to YES in the case that the // user has deleted the number at the start of the line bool goBackOneLine = NO; // Get a string representation of the current line number // in order to calculate cursor placement based on the // character count of the number NSString *stringPrecedingReplacement = [textView.text substringToIndex:range.location]; NSString *currentLine = [NSString stringWithFormat:@"%lu", [stringPrecedingReplacement componentsSeparatedByString:@"\n"].count + 1]; // If the replacement string either contains a new line // character or is a backspace, proceed with the following // block... if ([text rangeOfString:@"\n"].location != NSNotFound || range.length == 1) { // Combine the new text with the old NSString *combinedText = [textView.text stringByReplacingCharactersInRange:range withString:text]; // Seperate the combinedText into lines NSMutableArray *lines = [[combinedText componentsSeparatedByString:@"\n"] mutableCopy]; // To handle the backspace condition if (range.length == 1) { // If the user deletes the number at the beginning of the line, // also delete the newline character proceeding it // Check to see if the user's deleting a number and // if so, keep moving backwards digit by digit to see if the // string's preceeded by a newline too. if ([textView.text characterAtIndex:range.location] >= '0' && [textView.text characterAtIndex:range.location] <= '9') { NSUInteger index = 1; char c = [textView.text characterAtIndex:range.location]; while (c >= '0' && c <= '9') { c = [textView.text characterAtIndex:range.location - index]; // If a newline is found directly preceding // the number, delete the number and move back // to the preceding line. if (c == '\n') { combinedText = [textView.text stringByReplacingCharactersInRange:NSMakeRange(range.location - index, range.length + index) withString:text]; lines = [[combinedText componentsSeparatedByString:@"\n"] mutableCopy]; // Set this variable so the cursor knows to back // up one line goBackOneLine = YES; break; } index ++; } } // If the user attempts to delete the number 1 // on the first line... if (range.location == 1) { NSString *firstRow = [lines objectAtIndex:0]; // If there's text left in the current row, don't // remove the number 1 if (firstRow.length > 3) { return NO; } // Else if there's no text left in text view other than // the 1, don't let the user delete it else if (lines.count == 1) { return NO; } // Else if there's no text in the first row, but there's text // in the next, move the next row up else if (lines.count > 1) { [lines removeObjectAtIndex:0]; } } } // Using a loop, remove the numbers at the start of the lines // and store the new strings in the linesWithoutLeadingNumbers array NSMutableArray *linesWithoutLeadingNumbers = [[NSMutableArray alloc] init]; // Go through each line for (NSString *string in lines) { // Use the following string to make updates NSString *stringWithoutLeadingNumbers = [string copy]; // Go through each character for (int i = 0; i < (int)string.length ; i++) { char c = [string characterAtIndex:i]; // If the character's a number, remove it if (c >= '0' && c <= '9') { stringWithoutLeadingNumbers = [stringWithoutLeadingNumbers stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@""]; } else { // And break from the for loop since the number // and subsequent space have been removed break; } } // Remove the white space before and after the string to // clean it up a bit stringWithoutLeadingNumbers = [stringWithoutLeadingNumbers stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; [linesWithoutLeadingNumbers addObject:stringWithoutLeadingNumbers]; } // Using a loop, add the numbers to the start of the lines NSMutableArray *linesWithUpdatedNumbers = [[NSMutableArray alloc] init]; for (int i = 0 ; i < linesWithoutLeadingNumbers.count ; i ++) { NSString *updatedString = [linesWithoutLeadingNumbers objectAtIndex:i]; NSString *lineNumberString = [NSString stringWithFormat:@"%d ", i + 1]; updatedString = [lineNumberString stringByAppendingString:updatedString]; [linesWithUpdatedNumbers addObject:updatedString]; } // Then combine the array back into a string by re-adding the // new lines NSString *combinedString = @""; for (int i = 0 ; i < linesWithUpdatedNumbers.count ; i ++) { combinedString = [combinedString stringByAppendingString:[linesWithUpdatedNumbers objectAtIndex:i]]; if (i < linesWithUpdatedNumbers.count - 1) { combinedString = [combinedString stringByAppendingString:@"\n"]; } } // Set the cursor appropriately. NSRange cursor; if ([text isEqualToString:@"\n"]) { cursor = NSMakeRange(range.location + currentLine.length + 2, 0); } else if (goBackOneLine) { cursor = NSMakeRange(range.location - 1, 0); } else { cursor = NSMakeRange(range.location, 0); } textView.selectedRange = cursor; // And update the text view [textView setText:combinedString]; return NO; } return YES; }