錦鯉女王的生意經驗分享

https://tw.appledaily.com/life/20210604/4DJAUJWGFVH63DLFNNI4543XUA/

【鍾瑩瑩臉書全文 】

偶爾我會收到一些國外臉友給我的私訊,他會跟我說:

1.) 我有很多錢

2.) 我想買你的錦鯉

3.) 願望清單一份

4.) 請給我報價

5.) 什麼時候可以寄給我


然後,我會回覆他,麻煩提供我一下資料,我好給你報價單。

1.) 進口國際機場及代號

2.) 本國營業執照影本

3.) 進口核准函影本

4.) 隔離檢疫飼養環境的照片

5.) 門店銷售環境照片 + google Maps 定位

6.) 目前已採購的錦鯉照片

然後,80% 會已讀不回,20% 會繼續溝通:


1.) ABC 機場

有航班可以抵達,繼續討論。

沒有航班可以抵達,很抱歉我們供應不了。


2.) 營業執照

有營業執照,認真做生意來的。

沒營業執照,你是在家放幾個魚桶網路買賣嗎?


3.) 進口核准函

有核准函,有經驗來的。

沒有核准函,沒經驗的小白。


4.) 隔離設備環境

有設備,老手來的,折損率低。

沒設備,新手來的,死了病了都可能怪原產地品質不好⋯⋯


5.) 門店狀況+定位

看門店陳設就可以判定他會不會照顧魚、銷售狀況如何,有定位可以看當地城市概況商業活動概況。

然後我會幫他算機場到他的門店多長距離,正常交通時間多長,這樣可以決定包裝密度應該多少氧氣供應時間。包裝密度跟進貨成本息息相關,密度高運輸成本平均低,但密度高耗氧快,如果沒算好開箱時間,客人打開的時候可能都是缺氧的死魚的。

然後還要注意當地氣候溫度,氣溫高水溫高,我從產地要如何控制運輸期間的溫度,到了他開箱的時候落差不要太大,這樣魚兒才會蘇蘇糊糊的到新家。


6.) 目前商品狀況

可以判斷他的銷售對象大約什麼級別,可以判斷他需要的產品我們能不能提供類似的。也可以討論他目前商品的進貨成本,再換算在我們這邊採購成本會多少。也可以討論魚病他一般怎麼治療處理。

以上,了解對方的採購條件、運輸條件、飼養條件、銷售條件、專業經驗等等,我才可以放心的把產品賣給他,因為我不希望他出狀況的時候,千錯萬錯都推給賣方的錯。

大部分來回溝通,有的成為長期合作的客戶,有的只是同行要看報價單,有的是小白想創業發財,有的純粹詐騙集團來亂的。


有的還會跟我說:

可以不要這麼複雜嗎?我現在跟你訂!你就給我報價單,然後我會給你匯款,你用 DHL 寄給我就好啦!

這時候我會無語⋯⋯

你要我的報價做什麼呢?

就算你真的會給我匯款,DHL也不能寄魚啊!

國際空運帶水的活動物,都有一定規範,要走海關檢疫檢查才能放行,空運期間也要訂特殊溫控倉位,包裝方式也要符合國際規定。

你該不會淘寶買習慣了,覺得買一隻活的海豚跟買一隻卡通海綿寶寶一樣簡單吧?

然後對方會堅持讓我給他做報價單,也要我拍一些魚的照片給他看⋯⋯⋯有的還要我站在魚池邊上拍一些照片給他⋯⋯

這時候,我大約就理解了⋯⋯

果然詐騙⋯


他會拿著我的報價單、魚照片,然後跟別人說他跟我買過魚,這些魚都是他買的⋯⋯

我站在魚池旁的照片他還可以把自己P圖上去,假裝來過魚場跟我合照。

至於他這麼做的目的是為啥?

阿知,基本上創意大概是這樣⋯⋯

騙當地買家,他手上有的魚是我賣給他的。

騙國際賣家,他是有經驗的進口商。

騙他朋友投資,他是成功的錦鯉商人。

騙他老爸⋯⋯我是有出息的好孩子⋯⋯⋯⋯


總之,錦鯉買賣不是你給我寫信,我就可以賣給你。 我要考量我的產品賣給誰有合理的利潤,我的產品賣給誰可以有好的品牌效益,我的產品賣給誰可以有好的當地售後服務⋯⋯⋯


啊買一隻魚這麼麻煩?

嘿啊⋯⋯⋯

還有動物健康檢驗檢疫呢!


這又是一段長長的過程,不過這裡不需要說明可以跳過,大家也沒必要看太多跟自己生活不相干的產業內容。


啊所以,不是有錢就可以跨國跟產地買魚。

不是有錢我就會賣給你。

你可以許願,但不一定會實現。

專業合作才能雙贏。

感恩~~~


PS. 買一隻魚都這麼麻煩了,以此類推⋯


WHAT IS A CO-FOUNDER? 什麼是共同創始人?

https://slidebean.com/blog/startups-what-is-a-cofounder


What are the most important points in a co-founder agreement for a startup?

And finally, our last answer in this read. A co-founder agreement is essential to establish terms in a founder/co-founder team. It clarifies specific areas and business tasks and settles them according to a binding document we call an agreement. 

Transport all your needs to that record to avoid misunderstandings. Include in it everyone’s company ownership percentage along with the names of everyone in the founding and co-founding team. Add company goals along with each person’s roles and responsibilities. And outline how you’ll make the most significant decisions. Include equity breakdown, salary, compensation, intellectual property, and exit clauses. 

遠距工作注意事項

https://igoamazing.com/remote-work/


工作的契約型態主要分 2 大類:

(1) 外包、自由工作者(freelancer),簽的是以「承攬關係」連結的合約,不受雇於他人,可自由決定是否接受委託外包的專案、自由簽約,完全支配自己的時間,但通常要自己打理一切合約條款、發票、稅務,接案若不穩定,收入也會不穩定。

(2) 全職、兼職或約聘的遠距 / 遠端工作者(Remote full-time or part-time job, or contractor),簽的是有「雇傭關係」的合約,受僱於他人,必須遵守企業規範,能享有相關的勞工權益,不需進辦公室工作,工作時間可以是約定或彈性的。

簡單地說,第(1)類通常不管你是怎麼完成專案工作,只看最後交出的結果;而第(2)類仍是一個團隊進行工作,只是團隊成員不在同一個區域空間。


簽合約前須注意什麼?

首先,需瞭解契約型態,是委託外包以案計價?還是全職、兼職或約聘?相關稅務由哪一方來付?

接著,估算自己還要多花什麼成本,比如外包的合約通常比較像公司對公司的合作,「你」就是一人公司,所以其他財務作業如發票等需自行處理,有的公司甚至會要求你成立個人公司。

另外,大部分開出遠端工作職缺的公司,都是新創或外商,如果你受雇的是外商,比如美國,就必須簽 w8 表單,否則要繳稅給美國,還需考慮你必須自己負擔勞健保,以及從國外轉帳回國的手續費也不少。

https://www.reddit.com/r/digitalnomad/comments/94en4c/got_a_remote_job_from_the_usa_need_some_help_with/


如何跟其他人溝通合作、保持良好的互動?

在遠距工作中,最常用的溝通工具就是 Skype,或者有的會使用 Google Meet。由於對話時不一定會見到臉,無法觀察臉部表情,可能只有語音,所以不要害怕頻繁溝通,聽不懂的要主動詢問,不要吝嗇主動解答。

真的不誇張,我每天的 Skype meeting 裡,出現最多的一句話就是「Do you understand?」。如果每個人都願意花一點點溝通成本,就能避免誤會,減少浪費時間,推前工作進度。


https://m.facebook.com/FedTaxNote/posts/1229291071124591?comment_id=1229308887789476&reply_comment_id=1229312804455751

如果員工在台灣超過 183 天,會構成常設機構,美國公司可能需要到台灣報稅,看員工執行業務而定。


美國軟體工程師找實習與實習心得

https://chipaohong.medium.com/418c9eba4ade

Summer Intern, 是拿到公司正職最快且最不麻煩的方法。面一間公司的正職(Full-time)工作,可能要經過

OA(Online Assessment) → HR Phone Interview → Technical Phone Interview → Technical Phone Interview II(optional) → Onsite Interview (一整天面四五組人) → Team Match (optional) → Offer

相較來說,Summer Intern 的流程就簡單多了,少了困難的Onsite Interview,且可能只有一輪Technical Phone Interview,另外一輪只是聊聊天,分享自己的 Project 經驗。

OA(Online Assessment) → HR Phone Interview → Technical Phone Interview → Technical Phone Interview II(optional) → Team Match (optional) → Offer

Return Offer

公司收你當Intern,就是希望你畢業後能回來這裡工作,透過這幾個月的暑期實習,觀察這位候選人的表現。

如果候選人表現不錯,在實習結束前後一個月,會發 return offer 給候選人,據我所知,很多大公司的 return rate 都很高,甚至 90% 以上或是100% return 的。

Salary

美國 SDE Intern 的薪水還有福利可是很優渥的。


緯創事件點出印度管理問題,鴻海等台廠如何克服挑戰?

 緯創位於印度的 Narasapura 廠上週發生暴動事件,震驚業界。事件發生後,緯創現已解僱印度高級業務主管,同時重組團隊,並設立 24 小時的電話供員工匿名投訴。此次事件,雖說因工資爭議而引起,卻同時點出台廠在印度製造所面臨的「種姓制度」管理難題。

種姓制度是超級管理難題

緯創位在印度卡納塔卡省的 Narasapura 廠發生暴動,起因主要是工資爭議,有部分工人沒有按時得到報酬或獲得適當酬勞;然而,階級分明的種姓管理制度,或許才是本次暴動的潛藏禍根。印度「種姓」社會制度階級分明,社會地位低落的工人容易與管理人產生矛盾。

根據香港經濟日報報導,台灣企業在各國經營時,為了融入當地環境維持長期經營,多會推動人事在地化的策略。但是,印度的種姓制度,往往使得台商在實踐本土化管理時,要更小心處理階級問題;避免高階級的主管與低階級的員工出現矛盾或衝突。

對此,供應鏈人士也透露,台灣主管向來較常採用「搏感情」方式,與工人一起用餐、一起同歡,主管與工人間的階級沒有那麼明顯,做法也比較平等。但隨著在地化成趨勢,台灣製造廠開始聘用在地主管;由於印度有種姓制度,所以印度高階主管上任後,往往會一改過去台灣主管的平等作法或人事、勞務安排。這或許是緯創本次發生暴動的主要因素之一,使原本在緯創工作或已與緯創簽訂合約的勞務公司受影響,種下不滿因素。

也因此當地警方同時也在調查,是否有人為了宣洩不滿,鼓動基層工人暴動砸廠;卡納塔卡省工業廳長也表示,這起暴力事件可能是緯創與勞務公司和工人之間溝通不良所致。

如何管理維持穩定,女性員工或成一大關鍵

然而,緯創印度廠發生暴動後,並未影響台灣電子製造業者前進印度的計畫。像是和碩表示,大趨勢不受影響,會按先前規劃,印度廠最快明年下半年量產。鴻海也稱清奈擴產進度不會受此事件影響,同時鴻海與集團旗下富智康持續向印度政府申請生產獎勵。

這些持續實施印度製造策略的業者,究竟該如何因應種姓制度,維持管理、營運穩定?或許,鴻海去年已先實施關鍵策略,就是以女性員工為主。

2015 年,鴻海集團旗下富士康首座印度廠在印度安德拉省斯里市(Sri City)啟用;富士康印度工廠聘用將近 1.5 萬名勞工,女性約占九成,為多家公司組裝手機。第二座印度手機廠 2017 年在泰米爾納德省的斯利柏倫菩德(Sriperumbudur)開張,距第一座廠約 2 小時車程;這座廠聘用 1.2 萬人,廠房作業局部自動化。

在印度主管 Josh Foulger 領導下,印度富士康已成為重要的製造基地,未來也持續有擴廠計畫。那麼,為何會選擇以女性員工為主?Foulger 表示,事實上,他打從一開始就決定聘用女性勞工,因為執教鞭的母親說服他給婦女機會。

Foulger 透露,在印度,工廠女工不像中國那麼常見,鄉村婦女往往無酬做家事或進行農務;原本安德拉省斯里市甚至禁止女性輪值工廠夜班,直到當地政府和法院介入才改變;同時,也由於印度製造商大多偏好僱用男性,所以很輕鬆就達到招聘目標。

Foulger 強調,儘管必須增加保全、接駁巴士、宿舍等開銷,但這一切很值得,因為女性員工對獲得工作機會十分知足感恩,所以工作都十分賣力;同時多數印度女性工作時,心中都會有具體目標,像是償還家裡債務、讓小孩上更好學校等。

雖然此作法不能說是克服種姓制度的唯一解方,但鴻海印度廠以女性員工為主的特色,確實在營運管理保持一定穩定,並有利於未來擴產計畫;或許緯創事件發生後,此策略能供日後前進印度製造的台廠參考。


Progressive Web App 會是未來趨勢嗎?

https://blog.techbridge.cc/2016/07/23/progressive-web-app/


何謂 Progressive Web App (PWA)

先講結論,Progressive Web App 是希望能夠讓 Web application 盡可能的在各種環境(網路環境、手機作業系統等)下都能順暢且不減功能性的運作,並讓你的 Web App 可以:

  1. 直接被使用者安裝到桌面
  2. offline 使用
  3. 擁有推播功能
  4. 開啟時看不到 URL Bar(類 Native app 的使用經驗)
  5. 開啟時有 Splash Screen

而要做到這些事情,整個 PWA 的設計要點就會包含以下特性:

  • Progressive - 漸進增強:在越完善的環境下,能執行更加完整的服務,若環境不許可,能夠優雅降級,運行最基本的功能。

  • Responsive - 響應式介面:能夠在各種螢幕尺寸下顯示、能夠因應多種輸入方式與設備回饋(震動、音頻等)。

  • App-like - 類原生程式的操作模式與使用者介面:採用原生平台(Native App)的 Style 與資料更新方式(利用 service worker 存取快取資源)。

  • Fresh - 持續更新:使用 Service worker API 來自動更新應用程式(無需透過 App store, Google Play 等)。

  • Safe - 應全面採用 HTTPS 提供最基本的安全防護。

  • Discoverable - 透過設置 manifest 檔案,一樣能進行 SEO 優化,讓搜尋引擎找得到你的 APP。

  • Re-engageable - 透過推播,能主動與使用者互動。

  • Installable - 可安裝:透過 Add To Home 等方式,將 Web App 放在手機桌面,並且能在應用程式中單獨列出與切換,就像一般的 App 一樣,但完全不用透過應用程式商店下載。

  • Linkable - 透過 URL 可以隨時分享你的 App。

上面是官網所列出的,而紅色是我認為較為重點的特徵,而在這些重點特徵下,最大要點就是 Service worker。有了 Service worker 的幫助,你可以實作出離線可用的 Web App,讓 User 操作起來有更佳的使用體驗。

iOS 中 UITableView 和 自定義 UITableViewCell 的使用方法

使用纯代码自定义UItableviewcell实现一个简单的微博界面布局:https://www.cnblogs.com/wendingding/p/3761730.html


https://www.youtube.com/watch?v=2rd0FKN9XH8&list=PLzKtnppOmiXAYGqXEU_owKS-TH6FEZYeE&index=79


https://www.jianshu.com/p/f30eab24401f  頁庫存檔:

本文的重点并不仅是UITableView的基本使用方法,而是强调有关UITableView和UITableViewCell开发过程中的一些具体细节问题。基本信息请参阅Apple开发文档《Table View Programming Guide for iOS》。


概述

Table可能是最擅长于展示数据的一种UI部件。因此UITableView这个类是iOS App开发中除button和Label之外最常用的控件类型。几乎任何一个App都离不开tableView。使用UITableView很简单,核心就是要实现两个protocol。这是由于tableView在MVC中只是V这一环,所以它需要额外的支持提供另外的MC两个环节的功能才能让一个table完整的工作。而这种支持实现的途径就是protocol,Apple要求开发者提供实现** UITableViewDataSource** 和UITableViewDelegate 这两个protocol的支持类来协同对应的UITableView的工作。一般情况下,实现delegate protocol的类是UITableViewController,而data source protocol 可以是controller负责,也可以是其他helper类完成。但更多情况下,我更倾向于单独的modal wrapper类来完成。现在很多的建议data source尽可能不要放在controller中,这样有利于解决mass controller的问题。可以参考objc.io这篇文章:《Lighter View Controllers》


鉴于UITableView是如此的重要,iOS替我们定制化了两种类型的tableView:static和dynamic。前者适用于表格内容相对固定的场景,更多的使用在诸如Setting panel,Detail panel的地方;而后者适用于表格内容不固定,行数动态变化的场景,更多的使用在网络请求返回后,将动态的数据进行内容展示等。虽然Apple内置了几种(确切的说到目前为止是4种)table的style,但是对于App开发而言,大多数情况下都需要自行定制table对数据的展示方式,因此相对应的,table cell的定制化成为App开发的必修课题。


那么下文将介绍一下Static table的使用中需要注意的一些地方和dynamic table中cell开发的方法总结。


关于Static Table的报错

static table的设置方法很简单,在Xcode中设置UITableView的类型为static即可。

这里着重强调一个问题,绝大多数使用static table view的人都会遇到xcode报出的一个莫名其妙的错误:

error.png

而这个问题的原因是:放置static table的View Controller <u> ** 必须为iOS内置的UITableViewController类型 ** </u>

据说这是xcode的一个bug,但是到目前为止还没有被“修复”的迹象,总而言之,造成的结果就是,如果你想在某个页面放置一个static table view,你必须单独放在UITableViewController中,而且仅仅手动将自己的viewController的类继承自UITableViewController或者在xib中强制改成UITableViewController都不行,必须是原生的UITableViewController。可是很多情况下我们确实需要在自己的viewcontroller中添加一个static table view。怎么办?解决方法是使用Container View。


在你自己的ViewController中拖入一个Container View

删除这个Container View自动创建的segue和对应的target view controller

containerView.png

拖入一个新的UITableViewController,加入一个table view,修改类型为static;

Ctrl-drag container view到这个UITableViewController,在弹出的segue类型中选择Embed:

statictable.gif

当然,这种方式只适用于storyboard操作并且要求支持Container VC的iOS版本。在其他情况下,可以直接使用addSubView:,将UITableViewController的view(当然就是tableView)加到自己的“container”view之下。


UITableViewCell的使用方法

下文的重点是总结UITableView和UITableViewCell的核心方法。更多详情可以参考Apple的官方文档。


1. 预定义Cell

iOS自定义了4种常见的Cell格式,在UITableViewCell.h中的注释中Apple给了一些明确的提示这些预置的style一般都适用于什么场景:

typedef enum {
  UITableViewCellStyleDefault,  // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)
  UITableViewCellStyleValue1,  // Left aligned label on left and right aligned label on right with blue text (Used in Settings)
  UITableViewCellStyleValue2,  // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)
  UITableViewCellStyleSubtitle  // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).
} UITableViewCellStyle

4种类型在Xcode中对应的选项为:Basic, Right Detail, Left Detail和Subtitle。在iOS8下测试,对应的示例图如下:

Basic:

Basic.png

Right Detail有图时:

rightdetail1.png

Right Detail无图时:

rightdetail2.png

Left Detail:

leftdetail.png

Subtitle:

subtitle.png

在这4种格式都统一有3个property可以供你使用:

textLabel:一个主标题

detailTextLabel:一个副标题

imageView:一张详情缩略图片

实际上这些预置类型就是把这3种元素做了些取舍然后在不同的位置组合了一下。我觉得在设计App的时候,在任何情况下,设计师和工程师都应当首先考虑这些预置的类型能不能满足需求,除非有足够的必要,否则不要轻易的浪费经历在重复构造定制化的View上。个人觉得Subtile模式已经适用于绝大多数对UI要求不高的场合。你完全可以自己修改这3个控件的一些属性来对UI进行微调。比如你可以尝试将imageView的大小放大一些。


2. 自定义Cell

UITableView是通过调用UITableViewDataSource中的tableView:cellForRowAtIndexPath:方法来获取每一行所需要的Cell的,所以绝大多自定义Cell的处理过程都是在这一步完成,另外由于UITableViewCell本身也是一个UIView,所以你也可以在UITableViewDelegate中的tableView:willDisplayCell:forRowAtIndexPath: 方法中对Cell的view做最后的定制化。


注意: Apple明确指出,在tableView:willDisplayCell:forRowAtIndexPath:中应当只修改“state-based properties”,比如selection和background color等等,但是不应该是内容(content),也就是不要在这里进行任何数据处理。


2.1 自定义Cell的创建

有以下几种方法:

方法1:使用Code继承预定义的cell样式,然后再手动添加自己的view

这是Apple官方文档中的示例,它通过调用initWithStyle:reuseIdentifier:使用UITableViewCellStyleDefault参数来创建一个Cell,为了方便期间,我对代码稍做了些改动,一个是简化了数据加载,另一个是用NSTextAlignment替换了废弃的UITextAlignment:

  #define MAINLABEL_TAG 1
  #define SECONDLABEL_TAG 2
  #define PHOTO_TAG 3
  
  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CellIdentifier = @"ImageOnRightCell";
        static int i = 0;
        UILabel *mainLabel, *secondLabel;
        UIImageView *photo;

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if (cell == nil) {
              cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
              cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

              mainLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 220.0, 15.0)];
              mainLabel.tag = MAINLABEL_TAG;
              mainLabel.font = [UIFont systemFontOfSize:14.0];
              mainLabel.textAlignment = NSTextAlignmentRight;
              mainLabel.textColor = [UIColor blackColor];
              mainLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
              [cell.contentView addSubview:mainLabel];
  
              secondLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 20.0, 220.0, 25.0)];
              secondLabel.tag = SECONDLABEL_TAG;
              secondLabel.font = [UIFont systemFontOfSize:12.0];
              secondLabel.textAlignment = NSTextAlignmentRight;
              secondLabel.textColor = [UIColor darkGrayColor];

              secondLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
              [cell.contentView addSubview:secondLabel];
  
              photo = [[UIImageView alloc] initWithFrame:CGRectMake(225.0, 0.0, 80.0, 45.0)];
              photo.tag = PHOTO_TAG;
              photo.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
              [cell.contentView addSubview:photo];
        } else {
              mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];
              secondLabel = (UILabel *)[cell.contentView viewWithTag:SECONDLABEL_TAG];
              photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG];
        }

        mainLabel.text = [NSString stringWithFormat:@"Title_%d", i];
        secondLabel.text = [NSString stringWithFormat:@"Description_%d", i];
        i++;
        NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"];
        photo.image = theImage;

        return cell;
  }

最终效果如下:

CustomCell1.png

这里有两个重点:

Cell的重用机制

重用机制对于UITableView而言是非常重要的概念,这能够显著提高滑动TableView时的性能。如果不使用重用,那么每次新的Cell出现在屏幕上时都需要新创建一个,这对快速滑动而言是非常影响用户体验,并且会占用系统大量的内存开销。iOS的TableView使用的重用机制在原理上很简单,就是系统自动维护一个queue,这个队列放着一定数量的准备好的Cell UI object,滑出屏幕范围之外一定“距离”的Cell都会被回收到这个queue里,给马上要滑入屏幕范围内的Cell复用。

使用重用的方法核心是两个概念:Cell Identity和dequeue。前者是标识一种具体的Cell的id,后者是将Cell从复用队列中取出的实际操作。首先你需要用这个id告诉系统你将要用于重用的Cell是谁(注册),然后你使用这个id从重用的队列里取出来(复用)。具体到本例中的API就是如下两个:initWithStyle:reuseIdentifier:和dequeueReusableCellWithIdentifier:。后面将看到,对于不同情况下创建的Cell,注册和复用的调用也并不相同。

必须把自定义的控件添加在cell的contentView上,而不是view上,也就是:

 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
 ...
 // Correct!
 [cell.contentView addSubview:yourCustomComponetView];
 // Wrong!
 // [cell.view addSubview:yourCustomComponentView];

再次强调一点,Cell的Content View不是自己的root view。关于Cell View的结构可以参考这篇文章:《制作一个可以滑动操作的 Table View Cell》

这里只摘出最终结论,能够让你对一个Cell的view有直观的理解。

对于一个如图所示的Table而言:

sample.png


它的TableViewCell的View层级结构是:

<UITableViewCell; frame = (0 396; 320 44);> //1
   | <UITableViewCellScrollView; frame = (0 0; 320 44); > //2
   |    | <UIButton; frame = (302 16; 8 12.5)> //3
   |    |    | <UIImageView; frame = (0 0; 8 12.5);> //4
   |    | <UITableViewCellContentView; frame = (0 0; 287 44);> //5
   |    |    | <UILabel; frame = (15 0; 270 43);> //6

这个Cell 里有六个视图:

* UITableViewCell 这是最高层的视图。 Frame 显示它有 320 点宽和 44 点高——宽度和高度都和预期的一致,因为它和屏幕一样宽,而高度就是 44 点。

* UITableViewCellScrollView 虽然你不能直接使用这个私有类,但它的名字很好地暗示了它的功能。它的 Size 和 Cell 的一样。

* UIButton 它在 Cell 的最右边,就是 Disclosure Indicator 按钮。

* UIImageView 是上面 UIButton 的子视图,装载着 Disclosure Indicator 的图像。

* UITableViewCellContentView 另外一个私有类,它包含 Cell 的内容。这个类对于开发者来说就是 UITableViewCell 的 contentView 属性。但它只作为一个 UIView 来暴露在外,这就意味着你只在其上调用使用公开的 UIView 方法;而不能使用任何与这个类关联的任何私有方法。

* UILabel 显示 “Item #” 文本。


很显然,这里cell.contentView并不是cell.view。


方法2:使用xib绘制Custom Cell View

这是自定义Cell最常见也是最省力的方法:


首先在xcode中创建custom xib,拖拽需要的控件到xib上,并做好布局和限制;

2)新建自己的custom class,定义对应的outlet properties;

3)将xib的class设置成对应的custom class,然后将outlet和控件连接起来;

4)在适当的位置(一般为初始化的地方)调用registerNib:forCellReuseIdentifier:注册Cell;

5)在tableView:cellForRowAtIndexPath:中调用dequeueReusableCellWithIdentifier:forIndexPath:复用cell

下面的这个示例演示了上述步骤。在这个示例中,首先创建Custom Cell和xib的界面,其中有一张大图,下面有两个独立的label,然后我使用了tableView:willDisplayCell:forRowAtIndexPath:对每一行Cell的背景颜色做出最终设置,而在tableView cellForRowAtIndexPath:中对Cell的内容进行填充:


Custom View:

@interface MyTableCellView : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UILabel *name;
@property (weak, nonatomic) IBOutlet UILabel *date;
@end


Custom Xib:

CustomXib.png

在table View Controller中:

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup here ...

...

// register the cell to tell the system preparing to reuse it.

[self.tableView registerNib:[UINib nibWithNibName:@"TableCellView" bundle:nil] forCellReuseIdentifier:cellId];

}

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // always reuse the cell
        MyTableCellView *cell = [tableView dequeueReusableCellWithIdentifier:cellId forIndexPath:indexPath];
        
        cell.frame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 250);
        NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"];
        cell.imageView.image = [UIImage imageWithContentsOfFile:path];
        NSDate *object = self.objects[indexPath.row];
        cell.date.text = [object description];
        return cell;
    }

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"indexpath = %ld", indexPath.row);
        if ( indexPath.row % 2 == 0) {
          cell.backgroundColor = [UIColor redColor];
        }
        else {
          cell.backgroundColor = [UIColor greenColor];
        }
    }

Demo:

CustomCell2.png

方法3:使用code定义一个Custom Cell Class

这个在本质上和上一种使用xib的方法是一样的,只不过一个是用代码完全定制,一个是借助xib操作。但是在Cell重用的方式上有一定区别。上一种方法中,需要调用registerNib:forCellReuseIdentifier:来注册重用的Cell,在这里就需要用registerClass:forCellReuseIdentifier:方法来注册。与之对应的,获取重用的Cell的时候,调用dequeueReusableCellWithIdentifier:forIndexPath:方法。

Class myClass = [MyTableCellView class]; 
[self.tableView registerClass: myClass forCellReuseIdentifier:@"CustomCell"];
...
...
MyTableCellView *cell = [self.tableView dequeueReusableCellWithIdentifier:@"CustomCell" forIndexPath:path];
cell.label.text = @"text";
...

注意 dequeueReusableCellWithIdentifier:和dequeueReusableCellWithIdentifier:forIndexPath:的区别!!


如果你注册过Cell,在没有可用的cell时,前者会返回nil;而后者永远都会从注册的nib或者class中替你创建一个可用的Cell。也就是说,前者调用你需要手动检查nil,而后者不需要;

如果你从没有注册过cell,在没有可用的cell时,前者会返回nil,后者……直接崩溃!也就是说,调用后者你 必须确保注册过cell 。

2.2 访问Cell中的控件:

xib中使用outlet

这个应该不用多说,在Cell的原型中(不管是Static cell还是Dynamic cell)定义outlet properties,然后在xib中拖拽连接对应的控件即可;Apple官方文档上的示意图:


connect_outlet.jpg


connect_static_objects.jpg

代码中使用viewWithTag:

这个是获取parent view上某个特定view的快捷方法,首先需要设置一个sub view的tag,然后使用viewWithTag:来访问这个sub view。设置时可以通过xcode在xib中设置tag标签,也可以直接通过tag property手动设置:

创建时:

mainLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 220.0, 15.0)];
mainLabel.tag = MAINLABEL_TAG;
// customize the label here...
[cell.contentView addSubview:mainLabel];

访问时:

 mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG];

有关Table和Cell的性能需要注意的问题

关于这个话题,Apple并没有用过多的篇幅介绍,但是在官方开发文档中明确提出了3点意见:


注意重用(Reuse Cell)

这点我们已经在上文中着重强调过了。


避免反复的调整Cell的布局(Avoid relayout of content)

只在创建每一个Cell的时候布局一次,而不要每一次获取Cell的时候都去重新布局。


避免透明的subviews (Use opaque subviews)

自定义cell的时候,尽可能避免使用透明的控件,因为透明控件在table滑动时将增大渲染开销。


总结

本文主要从Static table和Dynamic table两方面总结了UITableView和UITableViewCell的核心使用方法和问题,并着重介绍了Custom Cell的几种方法和注意事项。


另外,有兴趣的话,UITableView还有另外几个比较关键的功能可以继续研究,一个是Editing mode,一个是Table Index,还有一个相对也很重要的功能自定义Header和Footer View。有空的话可以再总结一下。希望此篇能帮助到您。


2016年4月5日,完稿于南京。


團隊如果有一兩個人能力僅勉強勝任的話,會拉低團隊所有人的表現

 1.Netflix 創辦人海斯汀透過一場「關鍵裁員」,透析組織氣氛經營與人才篩選提高人才密度,對於Netflix的關鍵影響。

2.懶鬼、討厭鬼、憂鬱消極鬼,當團隊中出現這三種人,不論再優秀的團隊,其他成員也會被單一特定人士的行為影響,因而嚴重拖累團隊表現。


2001年春天,危機來襲。第一波網路泡沫破滅,無數網路公司倒閉消失。所有創投基金都中止了。我們一夕之間籌不到公司運作需要的周轉資金,而我們的公司又遠稱不上賺錢。公司士氣低迷,而且即將再往下挫,因為我們必須解雇1/3的員工。

我找馬克和派蒂.麥考德(Patty McCord)坐下來商量——派蒂是從Pure Software跟著我過來的同事,當時擔任人資長。我們仔細審核每一名員工的貢獻。沒有誰表現明顯特別差。所以我們把員工分成兩堆:80名表現最佳的員工,我們會留下;40名相較沒那麼出色的員工,我們會請他走。那些獨具創意、工作成績亮眼,而且與他人合作融洽的人,自然立刻分進「留下」那組。難是難在有很多介於及格邊緣的案例。有些人做同事做朋友都是好人,但工作表現平平。也有些人是工作狂,但判斷力不穩定,時常需要手把手地教。少數有幾個特別有才華,工作能力也強,但是愛抱怨或悲觀消極。這些人多半都得離開。可以想見,這個過程一點也不輕鬆。

我太太總說,宣布裁員前那幾天,我簡直如坐針氈。她說得沒錯,我擔心辦公室的士氣會盪到谷底。我深信在我打發了他們的朋友和同事以後,留下的人也會覺得公司待員工沒有誠信,所有人到時絕對都會很不滿。更何況「倖存者」還必須扛下離開的人的工作,可想而知一定會有很多抱怨。我們已經資金短缺,還承受得了士氣再瓦解嗎?

裁員的那一天到了,場面一如預期的難堪。被裁的人有的哭了,有的摔門,也有人氣得大吼大叫,到中午才告一段落。我則默默等待風暴進入下半場,也就是留下員工的反彈⋯⋯沒想到,除了幾許眼淚和明顯可見的悲傷之外,所有人都很平靜。接下來幾星期,氣氛大幅好轉,我一開始還不知道為什麼。我們依舊處於共體時艱的狀態,而且才剛裁了1/3員工,但辦公室卻突然活絡起來,迸發熱情、活力和創意。


幾個月後進入耶誕節假期,DVD播放機是那年熱銷的禮物。到了2002年初,我們的郵租DVD生意再度飛速成長。轉眼之間,我們的工作量翻升好幾倍——儘管員工數比之前少了1/3。令我驚奇的是,同樣是這80個人,他們處理所有工作的熱情似乎更勝以往。他們的工作時間拉長了,鬥志卻極高。不只是我們的員工變快樂,我早上醒來也等不及想去上班。那段日子,我每天順路載派蒂去公司,她也住聖克魯斯,每當我轉進她家門前,她幾乎都是雀躍地跳上車,臉上掛著大大的笑容說:「里德,這到底是怎麼回事?這就是戀愛的感覺嗎?難不成是某種化學作用,這種興奮感之後就會消退?」


派蒂講到了重點。整個辦公室感覺就像充滿了瘋狂愛上工作的人。


我不是在提倡裁員,而且也慶幸Netflix自此以後不必再做相同的事。但在2001年裁員風波之後那幾天,乃至於那幾個月,我發現了幾件事,徹底改變我對員工動力和領導責任的理解。我突然有所領悟,我對人才密度在組織中發揮的作用認知從此不同。我們從中學到的經驗,成為後來指引Netflix走向成功的基礎之一。


2001年裁員事件後,派蒂和我花了數十趟通勤車程討論這件事,想知道公司的工作氛圍怎會突然急轉彎向上,我們又該怎麼做,才能維持這股正向的動能。我們漸漸明白,我們的「人才密度」急遽提升,正是公司進步的推手。


優秀的人會幫助彼此進步更快

每位員工都具備某些才能。過去我們有120人的時候,有些員工才能出眾,另一些能力平平。總體來說,我們有相當的才能分散在全體人力之中。裁員以後,因為只留下最有能力的80個人,我們的才能總量減少了,平均每名員工的才能值卻提高了。因此,我們的才能「密度」提升了。


我們發現,人才格外密集的公司,也是人人都想效力的公司。高績效表現的員工在整體人才密度高的環境裡,尤其如魚得水。


我們的員工從彼此身上能學到更多,團隊的績效也更高。這又提升了個人的動力與滿足感,進而帶領公司整體實現更多成就。我們發現讓周圍環繞菁英,能讓原本已經不錯的成果彈射到全新境界。


最重要的是,與真正有才能的同事一起工作令人興奮、帶來鼓舞,而且充滿樂趣——相較過去只有80名員工,今日公司已有7000名員工也一樣。


我經由事後觀察發現,團隊如果有一兩個人能力僅勉強勝任的話,會拉低團隊所有人的表現。如果你的團隊有5名優秀下屬,另兩個差強人意,那這兩個勉強勝任的員工會:


耗盡主管心力,主管照顧優秀員工的時間減少。

降低團體討論品質,拉低團隊的總體智商。

迫使其他人必須養成另一套方法與他們共事,損害效率。

劣幣驅逐良幣,迫使追求卓越的人離職。

形同告訴團隊你能接受庸才,使問題更加複雜。

對優秀菁英來說,好的工作環境不在於辦公室裝潢鋪張、有漂亮健身房,或午餐有壽司吃到飽。身旁環繞有能力又懂得合作的人才,這些人又能幫助你變得更好,這種喜悅才是重點。當每個成員都很優秀,工作表現就會出現正向循環,員工能彼此學習、激發彼此的動力。


表現會傳染

你手下有平庸的人,會讓許多原本優秀的下屬也表現平庸。但若你的團隊全部由表現優異者組成,每個人都會激勵彼此做到更好。


澳洲新南威爾斯大學教授威爾.菲普斯(Will Felps)做過一項研究,結果令人驚奇,突顯了職場環境中行為的傳染力。他將大學生每4人一組,分成多組,請每組在45分鐘內完成一項經營管理任務。成效最好的一組可以獲得100美元獎金。

學生不知道,有些組內其實混入了演員,分別扮演以下幾種角色:「懶鬼」不參與討論,會把腳翹到桌上,傳簡訊和人聊天;「討厭鬼」會嘲諷挖苦,說些「你太扯了吧?」和「看來你根本沒上過商學課」之類的話;還有「憂鬱消極鬼」,臉上一副他家貓咪剛死掉的表情,抱怨任務做不到,質疑團隊不可能成功,有時還會乾脆趴在桌上。演員不會向其他組員透漏身分,其他人以為他們是一般學生。


菲普斯教授首先發現,即使小組中其他組員特別聰明又有能力,但一個人的不良行為仍會拉低全組的效率。這一個多月的時間,他進行了數十次試驗,組內有不良成員的組別,表現比其他組整整差了3成到4成。


這些發現顛覆了幾十年的研究,過去的研究多認為,團體內的個人會屈從團體的價值觀和行為準則。但事實卻是,某一個人的行為會快速感染團體其他成員,即使團隊才相處45分鐘。


菲普斯教授解釋:「令人驚訝且不解的是,團隊中的其他人為什麼會開始出現那個人的特質。」假冒者是懶鬼的時候,組內其他人也會對企劃失去興趣,最後總會有人跳出來宣稱任務其實也沒那麼重要。演員扮演討厭鬼,組內其他人也會開始互相羞辱,話中帶刺。演員如果是憂鬱消極鬼,影響最明顯。菲普斯說:我還記得我看到其中一組的影片。一開始所有組員都坐得直挺挺的,活力充沛,等不及想挑戰這個可能有難度的任務。但是到後來,每個人姿勢都垮了,頭都趴在桌上。」


菲普斯教授用實例說明了我和派蒂在2001年學到的事。團隊裡即使只有少數表現平庸的人,他們的表現仍有可能傳染給其他人,拉低整個組織的表現。


我們大多數人應該都能想起人生中有過的類似時刻,親眼目睹這種行為感染法則上演,我12歲時就見過一次。


我1960年出生在麻州。小時候的我很平凡,沒什麼特殊才華或出眾能力。小學3年級時,我們全家搬到華盛頓特區,生活過得還不錯,我也有一大群朋友。但到了6、7年級的時候,學校有一個叫凱文的同學,會聚集大家打架。他也沒有特別針對或霸凌我們之中的誰。他多數時候並不起眼,卻創造出一種行為模式,連帶影響了我們其他人的行為表現和相處方式。我很不想加入,但不參與打架感覺會比湊一腳還要丟臉。而且誰打輸、誰打贏,真的會決定大家一整天的氛圍。要是沒有凱文,我們彼此互動和一起玩的方式一定會大有不同。因此當我爸告訴我們要搬回麻州的時候,我簡直等不及立刻就走。


2001年裁員後,我們才發覺原本在Netflix裡,也有一小群人成就了令人不愉快的工作氣氛。從數不清的小地方看得出很多人不適任他們的工作,看在其他人眼裡則暗示公司可以接受平庸的表現,長久下來,就拉低了每個人的表現。


2002年,我們對於優良的職場需要具備的條件有了更多認識,我和派蒂立下承諾,我們往後的首要目標,就是要盡一切所能維持裁員後的人才密度,以及隨之而來的所有優點。今後我們會雇用最優秀的員工,支付業界最高的薪水。我們會訓練主管拿出勇氣和紀律,凡有不適任的行為或表現未達模範標準的員工一律裁除。我開始嚴格檢視,從接待櫃檯到最高執行團隊,確保Netflix的員工都是業界表現最佳、合作能力最強的人才。



程式語言編年史

程式語言編年史原文 下面這張圖片描繪了整個程式語言的歷史。包括各種程式語言的發明人、程式語言的特點和適用領域、被什麼網站或公司使用等 (檢視 完整高清圖 )。 之所以會有那麼多不同的程式語言是因為設計程式語言的初衷不同、對語言學習曲線的追求不同、不同程式之間的執行成本差異...