使用 FMDB 和 Obj-C 换行

Line breaks using FMDB and Obj-C

我对 iOS 编程比较陌生,所以请多多包涵。

我正在创建一个从 table 视图调用食谱的应用程序,然后在详细视图中将测量值和成分列为标签。我在 Google 表格中对我的食谱进行了分类,将其下载为 .csv 文件并使用 SQLiteStudio 填充了 table。然后我导出数据库,并使用 FMDB 将其放入我的应用程序中。那里一切正常,我能够检索各种字段。

我想做的是列出尺寸和成分,以便显示时换行:

0.5 oz. 1.0 oz. 1 jigger

而不是:0.5 oz., 1.0 oz., 1 jigger 这就是我将其写入 Google 文档的方式。

我曾尝试在 SQLite 查看器中使用 \n,但它会将其输出为字符串而不是将其编码为新行。但是,当我查看随附的 .sql 文件时,TextMate2 将其作为新行读取。我不确定是否必须在调用 FMDB 的 tableviewcontroller 实现文件中或其他地方应用一些代码。

我一直在寻找解决方案,但一直没有成功。任何帮助我朝着正确方向前进的帮助将不胜感激。谢谢!

CocktailListTableViewController.m

- (NSMutableArray *)recipeCocktails {
recipeCocktails = [[NSMutableArray alloc] init];

NSString *databasePath = [(AppDelegate *) [[UIApplication sharedApplication] delegate] databasePath];

FMDatabase *fmDB = [FMDatabase databaseWithPath:databasePath];

if(![fmDB open])
{
    NSLog(@"Could not open DB, try again");
    return nil;
}

FMResultSet *results = nil;
results = [fmDB executeQuery:@"SELECT * FROM recipesCocktails"];
NSLog(@"result %@ ",results);
if ([fmDB hadError]) {
    NSLog(@"DB Error %d: %@", [fmDB lastErrorCode], [fmDB lastErrorMessage]);
}
while ([results next]) {
    Cocktails *cocktails = [[Cocktails alloc] init];
    cocktails.recipeName = [results stringForColumn:@"recipeName"];
    cocktails.recipeMeasure = [results stringForColumn:@"recipeMeasure"];
    cocktails.recipeIngred = [results stringForColumn:@"recipeIngred"];
    cocktails.recipeGlass = [results stringForColumn:@"recipeGlass"];
    cocktails.recipeShaker = [results stringForColumn:@"recipeShaker"];
    cocktails.recipeDirections = [results stringForColumn:@"recipeDirections"];

    [recipeCocktails addObject:cocktails];
}

[fmDB close];

return recipeCocktails;

CocktailsDetailTableViewController.m

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = cocktails.recipeName;
self.recipeIngred.text = cocktails.recipeIngred;
self.recipeMeasure.text = cocktails.recipeMeasure;

这个问题有两种解决方法。

  1. 一种方法是将成分列表存储为单个文本字段,在字符串中使用换行符。 SQLite(和 FMDB)处理得很好。

    从 UI 的角度来看,您将以多行 UITextFieldUILabel 的形式显示此文本字段。如果您使用 UILabel,请确保将行数设置为 1 以外的值(即零或实际行数)。

    现在这里的技巧是将这个换行字符串输入数据库。这取决于你是如何做的。但是如果你使用一些 SQLite 工具,你不能使用 \n 序列,因为那不是 acceptable SQL 语法。您可以使用 x'0a'char(10):

    insert into foo (bar) values ('baz' || x'0a' || 'qux');
    

    或:

    insert into foo (bar) values ('baz' || char(10) || 'qux');
    

    或者,如果使用 SQLite 命令行工具,您可以只插入换行符:

    insert into foo (bar) values ('baz
    qux');
    

    但是你不能使用\n序列。您可以通过 Objective-C 代码执行此操作,但不能通过第三方 SQLite 工具执行此操作。

  2. 另一种方法是将食谱列表和每个食谱的配料列表存储在两个不同的 table 中(例如 recipesingredients ).然后,您可以将每种成分存储在 ingredients table.

    中的单独行中

    我觉得这是一个更合乎逻辑的实现。如果你这样做,你就可以选择如何显示成分列表(单独的 UILabel 控件,一个 UITableView,或者,如果你真的想要,将它们连接在一起,用换行符分隔并在单个多行控件中显示它们。

我看到您正在尝试将所有成分存储为一个长的、预先构建的字符串,我认为这种方法不是最好的。

它会起作用,但它不是面向未来的,或者只是......通常。

我强烈建议有一个新的 table,它知道所有可能的成分,带有 ID 和您意愿的其他信息(颜色、平均重量、图片* 等等)

( 请注意,不建议将图像存储在 SQL 数据库中,您更愿意将引用存储到将它们保存为文件的位置或 URL的)*

一旦你拥有 table,你就是黄金。您只需在食谱中引用一系列成分 table。例如 [1,27,133],这样你就可以做你想做的事了。您有一组成分对象,您可以根据自己的喜好进行处理。

例如,我会在它上面循环并在彼此下面创建标签,这样你就有了你的台词。 我也可以简单地使用 NSMutableString 并用 ingredients.name 填充它(再次使用示例) 您可以在每个成分之间用换行符填充 UITextView(通过使用 NSMutableString 并在每个对象名称之间添加换行符)。

更重要的是,您可以修改所有内容,而无需重新设计布局或标签或重新编写整个数据库,因为每个食谱都有静态换行成分。

这是我想表达的最重要的一点。使用这种方法,您可以从任何食谱中删除任何成分,而不必考虑太多或冒忘记某些事情的风险。您还可以通过将其从成分 table 中移除来永久销毁每个食谱的任何成分。添加新的也一样。或者说您想更改成分 X 的名称,您不必在每个食谱中都这样做,等等。

编辑:在评论中回答您的问题

要在 table 视图中加载食谱并在详细信息页面中加载成分,您可以这样做:

  • 您将所有食谱加载到一个数组中并显示(我认为您已经在这方面取得了成功)。 请注意,所有食谱都有一个名为 "Ingredients" 的 属性,它是一个成分数组 keys/ids/something

  • 在单元格点击时,您想加载您只知道其 ID 的成分,您只需从存储在食谱中的 ID 数组中获取它们,然后 SELECT他们来自你的数据库。

在全球范围内,在用户点击之前您不知道成分是什么:如果您不需要在 table 视图中显示它们,那么您还不需要加载它们。但是你已经知道他们的id了(否则你就找不到他们了!)。