1. 程式人生 > >一鍵修改工程中xib/Storyboard中的顏色

一鍵修改工程中xib/Storyboard中的顏色


可以直接下載用(注意路徑中不要有中文),感興趣就看看文章 .

2018.9.2

這個改色的小工具,本來是我自己在工作中,碰到的需要解決的問題,就做了一個這樣的小工具,當時僅限滿足自己的需求,但是最近有簡友留言,提出有bug,還提出了一些改進的意見(多謝@燈塔的焰火),本是打算,趕緊修復一些這些問題,怎奈懶癌病犯,以至拖到今日,實在慚愧!。。。

此次優化如下:

-> 1,優化了匹配色值演算法;
-> 2,優化顏色資料模型ColorValue;
-> 3,優化結果提示,失敗情況下用紅色,修改完成則用綠色;
-> 4,修改完成後,恢復初始狀態,以節省資源,提高效能;

如果此工具對你有幫助,那就順手給個star吧 -> star

2016.12.22

最近有點閒了,所以就把以前的這個小工具更新一下,這麼長時間,還經歷過一次Xcode8的更新升級,估計這個小工具是不能用了,開啟工程cmd+R了一下,發現還真的不能用了,索性給這個小工具來一次升級。

使用上的一些改進:

1. 我做了一個很好用的介面,你可以在介面上進行顏色值得操作;
2. 可以點選檔案路徑 進行選擇所需要修改的檔案的路徑。

simple1.png

simple2.png

simple3.png

程式碼的優化:

1.先簡單說下原理:

-> 分別記錄修改前(beforeColor)和修改後(afterColor)的顏色模型, 以及檔案路徑(filePath);
-> 將使用者輸入的顏色值轉化為所需要的型別,也就是將顏色值->ColorValue模型;
-> 遍歷filePath路徑下,所以有的.xib和.storyboard檔案,並儲存檔案路徑;
-> 對每一個.xib和.storyboard檔案進行DOM解析操作,找到所有color元素標籤NSXMLElement;
-> 找到color元素標籤內的NSXMLNode相對應的node.name,over。

2.一些核心程式碼:

  • 記錄顏色,這個就是textField的一個delegate方法, 檔案路徑的選擇,用的這個NSOpenPanel;

    // NSTextDelegate 獲取輸入內容
    - (void)controlTextDidChange:(NSNotification *)notification;
    
    //  獲取檔案選擇路徑
    - (IBAction)choseFilePath:(NSButton *)sender {
        NSOpenPanel *openPanel = [NSOpenPanel openPanel];
        [openPanel setCanChooseFiles:YES];
        [openPanel setCanChooseDirectories:YES];
    
        NSWindow *window = [[NSApplication sharedApplication] keyWindow];
        [openPanel beginSheetModalForWindow:window completionHandler:^(NSModalResponse returnCode) {
            if (returnCode == 1) {
                NSURL *fileUrl = [[openPanel URLs] objectAtIndex:0];
                NSString *filePath = [[fileUrl.absoluteString componentsSeparatedByString:@"file://"] lastObject];
                NSLog(@"fileContext = %@",filePath);
                self.sourcePathTextField.stringValue = filePath;
                self.filePath = filePath;
            }
        }];
    }
    
    
  • 顏色資料模型ColorValue;

    // 直接儲存 轉化後RGB色值,_redValue為CGFloat型別,作為匹配參考值,這裡擷取小數後8位,作為要修改的色值
    - (void)setRedValue:(CGFloat)red {
        CGFloat tempValue = red / 255.0;
        _redValue = tempValue;
        self.red = [NSString stringWithFormat:@"%.8f",tempValue];
    }
    
  • 色值匹配演算法;

    // 相比較以前的容錯演算法來說,這樣的寫法更簡潔,在此,暫時將相似精度值設定為0.0001
    - (BOOL)isEqual:(WDColorModel *)object {
    
        BOOL redEqual = fabs(self.redValue - object.redValue) < 0.0001;
        BOOL blueEqual = fabs(self.blueValue - object.blueValue) < 0.0001;
        BOOL greenEqual = fabs(self.greenValue - object.greenValue) < 0.0001;
        
        return redEqual && blueEqual && greenEqual;
    }
    
  • 搜尋.xib和.storyboard檔案,這個沒什麼說的,就是檔案操作,檢索檔案字尾;

  • 獲取color元素(NSXMLElement),並操作修改;

  // 獲取 XMLDocument
  - (NSXMLDocument *)parsedDataFromData:(NSData *)data colorModel:(WDColorModel *)objColorModel {
      NSError *error = nil;
      NSXMLDocument *document = [[NSXMLDocument alloc] initWithData:data options:NSXMLNodePreserveWhitespace error:&error];
      NSXMLElement *rootElement = document.rootElement;
      [self parsedXMLElement:rootElement objColorModel:objColorModel];
  
      if (error) {
          NSLog(@"error = %@",error);
      }
      return document;
}

  // 修改元素
  - (void)parsedXMLElement:(NSXMLElement *)element objColorModel:(WDColorModel *)objColorModel {
      for (NSXMLElement *subElement in element.children) {
          if ([subElement.name isEqualToString:@"color"]) {
            WDColorModel *obj = [WDColorModel colorModelWithArray:subElement.attributes];
              if ([obj isEqual:self.targetColorModel]) {
                  [self updateXMLNodelWithNode:subElement color:objColorModel];
              }
          }
          [self parsedXMLElement:subElement objColorModel:objColorModel];
      }
}

  // 更新 NSXMLElement
  - (void)updateXMLNodelWithNode:(NSXMLElement *)subElement color:(WDColorModel *)obj {
       NSArray *array = subElement.attributes;
       for (NSXMLNode *node in array) {   
          if ([node.name isEqualToString:@"red"]) {
              [node setStringValue:obj.red];
          }
          else if ([node.name isEqualToString:@"green"]) {
              [node setStringValue:obj.green];
          }
          else if ([node.name isEqualToString:@"blue"]) {
              [node setStringValue:obj.blue];
          }
       }
  }

具體細節見程式碼,如果覺得不錯,那就順手start